在数据库表设计中,以下哪一项更适合事件日志类型的数据增长
设计1)数字列(长)和字符列(Varchar2) 指数:
..(pkey)|..|..|StockNumber Long | StockDomain Varchar2 |...
.. |..|..|11111 | Finance
.. |..|..|23458 | Medical
设计2)具有索引的字符列Varchar2:
..(pkey)|..|..|StockDetails Varchar2(1000) |..|..
.. |..|..|11111;Finance |..|..
.. |..|..|23458;Medical |..|..
设计优势:第一种设计非常具体,第二种设计更加通用,可以容纳更多的一般数据。在这两种情况下,列都是索引的。
存储:第一个设计索引需要的存储量少于第二个 表现:相同吗?
我对性能与灵活性有疑问。显然,第一次设计更好。但第二种设计是更普遍的目的。让我知道你的见解
注意:编辑问题以获得更清晰的信息。
答案 0 :(得分:2)
在关系数据库设计中,您需要离散列。每行每列一个值。
这是使用数据类型和约束来实现某些数据完整性的唯一方法。在第二个设计中,如何在StockNumber或StockDomain上实现UNIQUE约束?你如何确保StockNumber实际上是一个数字?
这是在每个列上单独创建索引的唯一方法,或者创建一个将StockDomain放在第一位的复合索引。
作为类比,请查看电话簿:你能找到所有姓名为"比尔"容易还是有效?不,你必须搜索整本书才能找到具有特定名字的人。索引中列的顺序很重要。
第二种设计实际上根本不是数据库 - 它是文件。
为了回应你的意见,我重申我在评论中所写的内容:
有时非规范化是值得的,但我不能告诉[你的第二个设计是否值得],因为你还没有描述如何查询这些数据。在决定进行任何优化之前,您必须考虑您的查询需求。
换句话说:与其他所有优化一样,非规范化会使一种查询类型受益,会牺牲其他查询类型。因此,您需要知道哪些查询需要最优,哪些查询不太重要,因此如果其他查询降级,它将不会损害您的整体性能。
如果您无法预测查询,则默认使用规范化规则设计数据库。规范化不是为性能优化而设计的,它旨在防止数据异常,这也是一个很好的目标。
您已经发布了几条新评论,我希望我会突然理解并认可您的第二个设计。但您仍然没有描述任何将使用您的第二个设计进行优化的特定查询。
答案 1 :(得分:2)
一般而言,由于以下几个原因,使用离散列是更好的方法:
数据类型 - 您可以保证您保存的数据格式正确,至少就非字符串列而言,如果它是bigint / long,则stockNumber将始终为数字,尝试设置它的任何其他内容都会导致插入/更新错误。作为冒号分隔值(CSV)字符串的一部分,如果它是字符串的一部分,则可能存在错误数据。
查询 - 由于您要查找单列字符串的子字符串,因此必须使用LIKE
查询单个列。如果我查找WHERE StockDetails LIKE '%11111%'
,我会找到第一行,但我可能会找到另一行,其中该列中的美元值,在另一个字段中为$ 11111。对于离散列,您的查询将为WHERE StockNumber = 11111
,以确保仅在该列中查找数据。
使用数据 - 一旦找到了您想要的行,就必须读取数据。这意味着将CSV解析为单独的字段。如果其中一个字段中有一个冒号,并且它被不正确地转义,则其余数据将被解析错误,并且您仍然需要保证相同顺序的值,并留下空白部分;;
你会在列中得到一个空值。
存储CSV和单独的列之间存在中间立场。我已经看到了,实际上我正在做一个主要项目,数据存储在一个表中作为json。使用json你有属性名,所以你不关心字段在字符串中出现的顺序,因为域仍然总是域,你在条目中不需要的任何非标准字段(比如只存在的属性)医学领域)将不会在那里,而不是需要一个空白的双冒号,json的解析器存在于我能想到的所有语言中,你将连接到你的数据库,没有必要手动编写一些东西来解析你的CSV字符串。例如,上面给出的StockDetails看起来像这样:
+--------------------------------------+
| StockDetails |
+--------------------------------------+
| {"number":11111, "domain":"Finance"} |
| {"number":23458, "domain":"Medical"} |
+--------------------------------------+
这解决了上面的问题2和3:
WHERE StockDetails LIKE '%"number":11111
,包括json属性名称,以确保您无法在字符串中的任何其他位置找到数据。