【问题标题】:Redis vs MySQL for simple databaseRedis vs MySQL 用于简单数据库
【发布时间】:2016-11-15 02:23:10
【问题描述】:

我想创建一个简单的数据库,该数据库必须存储节点、它们的功能和地址,以便在出现问题时通知。最初我在考虑使用一个简单的 SQL 数据库:

CREATE TABLE IF NOT EXISTS push_notifications (
  node text NOT NULL,
  functionality text NOT NULL,
  address text NOT NULL,
);

其中节点和功能可以有多个地址,N 到 N。这种获取地址的方式我将执行以下两句话:

SELECT address from push_notifications where node=XX and functionality=YY;
SELECT node, functionality from push_notifications where address=XX ORDER BY node, functionality;

但是看了一点之后,我有几个疑问:

  • 对于最初不会超过 10000 个条目的数据库可以吗?
  • 我是否应该使用规范化的方式来组织表,即一个用于节点,另一个用于功能,另一个用于地址以及在 SELECT 中使用 JOIN?那么,如何自动删除不再链接的表中的条目,即没有功能且没有端点的节点?
  • 我是否应该使用像 Redis 这样的简单数据库引擎,将键设置为节点功能(字符串和值是地址列表),并将另一组键设置为端点(哈希)?

我想补充一点,我将使用 Java 来处理对数据的访问。

感谢您的帮助。我真的很感激并建议什么是做这种事情的最佳方式。

编辑:选择多个简单表格的选项(我认为还可以)

 CREATE TABLE IF NOT EXISTS node (
   id integer PRIMARY KEY AUTOINCREMENT,
   iri text NOT NULL,
   UNIQUE(iri) ON CONFLICT IGNORE -- ON CONFLICT REPLACE
 );

 CREATE TABLE IF NOT EXISTS functionality (
   id integer PRIMARY KEY AUTOINCREMENT,
   name text NOT NULL,
   UNIQUE(name) ON CONFLICT IGNORE -- ON CONFLICT REPLACE
 );

 CREATE TABLE IF NOT EXISTS address (
   id integer PRIMARY KEY AUTOINCREMENT,
   url text NOT NULL,
   UNIQUE(url) ON CONFLICT IGNORE -- ON CONFLICT REPLACE
 );

 CREATE TABLE IF NOT EXISTS push_info (
   node integer NOT NULL,
   functionality integer NOT NULL,
   address integer NOT NULL,
   UNIQUE(sensor, endpoint) ON CONFLICT IGNORE, -- ON CONFLICT REPLACE
   FOREIGN KEY(node) REFERENCES node(id) ON DELETE CASCADE
   FOREIGN KEY(functionality) REFERENCES functionality(id) ON DELETE CASCADE
   FOREIGN KEY(address) REFERENCES address(id) ON DELETE CASCADE
 );


 SELECT address.url as address
   FROM address
 INNER JOIN push_info
     ON address.id = push_info.address
 INNER JOIN node
     ON node.id = push_info.node
 INNER JOIN functionality
     ON functionality.id = push_info.functionality
 WHERE
   node.iri = "node1" AND
   functionality.name = "functionality1";

【问题讨论】:

  • 你的数据结构不清楚。是否可以将任何节点与任何功能和任何地址组合(以及任何具有任何节点和功能的地址等),但并非所有这些都自动存在?然后你会得到一个这样的表。虽然我不会使用text 标识符,但您可以使用varchar(并确保您只输入有效值并将它们视为代码)或使用包含所有函数和节点(可能还有地址)的 2-3 个查找表并使用他们的 id 或代码进入该表。
  • @Solarflare 正如你所描述的那样,多个节点可以具有相同的功能和地址,就像一个所有的一切。查找表是我建议的规范化选项,其中我有一个节点列表、一个函数列表和一个地址列表。然后使用一张表,我将加入每个表的 ID。是不是很耗资源?或者它是更好的选择。还是使用 Redis 方式更好?
  • 您的表格按原样进行了规范化。使用 3 个查找表与规范化无关,只有在需要时才需要这样做,例如除了您的键之外的描述或任何其他数据(可以是字符串,尽管我会使用 varchar,并保持它们简短,最好是非 utf8),或者如果您想使用外键验证值.否则,如果您想用一些整数 id 替换它们,这取决于您的个人喜好。 redis 或 mysql 也一样。 10k 行不会对性能产生任何影响,所以这是个人喜好。只需添加索引。
  • @Solarflare 非常感谢。我将使用varchar。但是您建议使用 3 个查找表和连接的一个,不是吗?那么,如何删除未使用的引用?在其中我包含删除一行,而在 3 个查找表中我必须检查引用。
  • 您的消息没有说明您要做什么或要问什么。 请解决您问题的第一条评论。您没有清楚地解释自己。您的文字是指您没有解释或与您的表格相关的事物。请花时间表达你想要达到的目标。我们无法读懂你的想法。 (例如什么是端点?例如我的回答已经解释了“节点和功能可以有很多地址,N 到 N”是没有帮助的。PS 当没有这样的列时,唯一的(传感器,端点)有什么用?

标签: mysql redis database-normalization


【解决方案1】:

标准化你有一张桌子。在您开始“规范化”或开始谈论“规范化”之前,请了解什么是规范化。这是关键问题:您能否用较小的表替换此表,以便它们始终加入其中?为此,在给定的应用程序情况下,必须可以将行在表中的标准表述为一个或多个 AND 的“... AND ...”。如果可以,标准化可能会建议进行替换。如果你不能,它就不会。 (基数通常不允许我们确定。)

更多的表只有你才能知道是否要存储这张表不能告诉你的信息,以便你需要更多的表。例如,如果您想记录一个特定节点存在,即使它不参与该表所代表的应用关系,那么您需要另一个表。

关系型 vs 非关系型关系型数据库允许通用声明查询和完整性实施,但有一定的实施成本(以及一些自动优化)。其他数据结构都支持专门且主要是非声明性的查询和完整性执行,实现成本有所提高,但其他情况通常很尴尬和/或昂贵。您必须了解您的使用模式以及成本和收益如何在这些众多维度之间进行权衡,以便确定哪种设计是“最好的”。我们总是可以合理地从关系设计开始,然后在必要和期望的地方进行专门化。

【讨论】:

  • 我的主要问题是,我不知道只有一个表,复制字符串并在其上搜索是否真的会降低性能,或者拥有简单的表并连接表和搜索会更好通过 where whaterver 等于字符串。看看编辑过的问题。哪个选项更好?并且更易于管理?考虑插入、选择和删除。
  • 根据我的回答,当我们规范化时,我们“用较小的表替换此表,以便它们始终加入它”。用 id 替换列不是规范化。如果您要询问将带有字符串列的表替换为带有 id 列的表以及一些将 id 映射到字符串的表,那么 say so。 (即努力寻找说这句话的单词和句子。就像我刚刚做的那样)。它显然使架构和查询复杂。但根据我的回答,“最佳”depends。 PS您的问题中没有关于此的nothing。我从您的代码和此评论中猜测。
  • 如果你想“优化”那么你首先需要了解设计,然后了解查询同一事物的多种方式了解您的特定 DBMS 中的优化。另外,要与替代系统进行比较,您必须了解它的相同之处
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
  • 2018-05-29
  • 2016-09-15
  • 2015-08-04
  • 1970-01-01
相关资源
最近更新 更多