![]() |
1
9
首先,关系数据库不是为存储任意数据而设计的。关系模型的基础在于获取将要存储的数据的性质的规范。 其次,您建议的是实体属性值(EAV)的变体。EAV的问题在于数据完整性、报告、性能和维护。它们有它们的位置,但它们类似于药物:在有限的数量和狭小的环境中使用它们会有益;过量会杀死你。
针对EAV编写查询是一种负担。因此,如果您要使用EAV,我看到它们成功的唯一情况是限制它们的使用,这样就不允许任何人编写筛选特定属性的查询。也就是说,不允许任何人编写类似于
现在,如果您在这里使用EAV,并且因为它只是一个数据块,所以我将使用单表方法。单表方法的一个显著好处是,您可以添加一个检查约束,以确保在IntValue、StringValue或DateValue列中只有一个值。空值不会花很多钱,如果这只是一堆数据,它不会对性能产生任何影响。此外,它还可以简化查询,因为您可以使用简单的case语句返回字符串、整数或日期值。 我可以看到多表方法的许多问题,其中最不重要的是,没有什么可以阻止同一属性具有多种类型的值(例如,integervalues中的一行和stringvalues中的一行)。此外,要获取数据,您必须始终使用三个左联接,这将使您的查询编写起来更麻烦。 电动汽车的成本是纪律和警惕。它要求开发团队中的规程在任何情况下都不要针对特定属性编写报告或查询。开发人员将从管理层得到很大的压力,“只是这一次”写一些特定属性的过滤器。一旦你永远走在黑暗的道路上,它就会支配你的开发和维护。EAV必须保持一堆数据,而不是更多。如果您不能在开发团队中保持这种纪律,那么我就不会实现EAV。为了避免以后的维护噩梦,我需要为任何新列提供规范。一旦用户确实希望对报表进行筛选、排序、计算或将属性放在特殊位置,则该属性必须成为第一类列。如果您能够维护它们的使用规则,那么EAV可以很好地让用户存储他们想要的任何信息,并推迟您需要获取数据元素规范的时间,直到用户希望以前面提到的方式使用该属性。 |
![]() |
2
3
我更喜欢将键和值放在一张表中。 我现在正在建立的数据库以简单的主语/谓词/宾语短语收集关于汉字的数据点;主语和谓词都是字符串,但对象可以有任何类型。表中有一些额外的结构信息(如谓词类型),但不多。 我的数据库结构的一个特殊特征是谓词实际上被分割成几个部分键。要了解这是如何有用的,让_s考虑字符_:的一些数据点:
每行代表一个数据点。第一个元素是主语,最后一个是宾语,中间是谓词部分。谓词部分有一个固定的列数(3到5列很可能足够“平坦”比嵌套更好);未使用的部分接收空值。使用此模式,可以很容易地构造SQL语句,返回有关给定字符的所有事实,或有关若干给定字符的所有日语读数(on和kun),或具有至少13个和最多24个笔画的所有字符,等等:
这种方法的好处在于,如果没有太多的思考和预先计划,您很快就可以开始向表中输入数据。当新的事实出现时,它们大多数时候都会适合这个非常一般的结构;当你发现某些谓词很笨拙时,收集违规记录并更新它们以携带你最喜欢的新措辞并不太困难。不再迁移架构。哎呀! 更具体地说,为了回答您的问题,我考虑了很多关于是否将值放在单独的表中,以及是否在另一个表中实际表示谓词的问题。
这是完全可能的,但对于我最初的版本,我发现了它
更重要的是保持简单
;如果在某种程度上,存储所有这些repetitve字符串会损害存储和性能(我的意思是,我的数据库中有大约70000个字符的strokeCounts,因此仅此顺序是
当我听到有人声称当然你必须把那些重复的谓词和不同的值类型放在不同的表中时,我只是礼貌地微笑。 数据库已经优化了几十年,以应付大量的数据和有效地组织稀疏表,该死。 我的意思是,整个方法都违背了每个人都告诉你如何去做的,所以为什么不大胆一点呢? 最后,我认为有三个主要因素可以帮助您决定如何构建数据库: 1)您能想出合理的SQL语句吗? 给你期望的答案?(如果不是这样,您还必须决定是否遇到了SQL的一个固有限制,一个可能或可能无法用不同的DB模式解决的限制)。 2)这些查询是否表现良好? 我从经验中知道,用另一种方式(在一些MB的sqlite-db中)可以在性能上产生巨大的差异,因此即使您选择了一种大表方法并获得不满意的查询时间,也可能是模式出了错,但选择另一种查询相同数据的方法也可能会导致你的速度提高了10倍。 3)可扩展性。可扩展性。可扩展性。 这是一个困难的问题,但也许你知道你所要做的就是收集关于你个人大理石收藏的数据。在这种情况下,很难做出错误的决定。如果你承诺在不到一秒钟的时间内将你国家出版的任何一本书上的数据传送到世界上的每一台桌面,那么很难做出正确的事情。大多数现实场景都介于两者之间,所以可伸缩性意味着要问:如果这个或那个工具最终成为性能瓶颈,我是否能够升级它,或者失败地迁移到另一个产品?我说,一张大桌子的方法非常简单,替代方案应该是丰富的。 啊,也许你会感兴趣:我正在调查 redis 这是一个不时髦的数据库。它看起来很有趣,而且很容易使用。“一个大表”方法应该与那些非常流行的couchdb/mongodb/whathaweyou_document-oriented,schema-free__数据库非常兼容。 |
![]() |
3
1
我肯定会使用多表方法,这将使您的查询更简单,并消除许多未使用的字段。如果您希望规范化您的数据库,您还应该将键分离到一个额外的表中,但这只是一个优先事项。 我能想到的唯一更好的方法是使用面向文档的数据库,比如 MongoDB . |
![]() |
4
1
将值存储为原始二进制 通过将数据转换为原始字节[]格式,将值存储在varbinary字段中。 为什么把所有的东西都转换成弦很糟糕: 将所有内容转换为字符串非常昂贵,因为它们实际上是一种转换。 例如: ints、double、float、bools、dates等…所有这些都需要转换成ASCII字符,这在存储和处理方面都是昂贵的(特别是因为它们需要转换回)。 相信我,我以前做过这样的工作,把所有的东西都转换成双精度(我只使用标量值),它起作用了,但很糟糕。 如果将所有内容转换为bytes[],则不存在“real”格式转换,因为您正在复制类型的基元版本。唯一的补充是,您还必须存储类型,这样当您将数据从表中拉出来时,您就知道如何将其转换为数据。 您有两种选择:
例如:
有时,知道如何使用二进制和字节[]是一个巨大的优势。 更新 我不清楚为什么这次投票被否决。它满足了包含简单的每行键值对关系的问题要求。考虑到不需要向表中添加不必要的列,以及以二进制表示形式存储的“本机”格式的值,这也是一种快速而高效的方法。 它增加了从表中插入/提取项的额外步骤,但是普通字典/数组在较低的级别上也会这样做。唯一的主要区别是,这种存储值的方法携带着它的类型。 这种方法唯一真正的缺点是:
|
![]() |
Michael Samuel · MYSQL在以下情况下自动创建索引 6 年前 |
![]() |
Patricia Rozario · 数据库设计确保一对一关系 6 年前 |
![]() |
dryhay · MySQL“多对多”关系错误 6 年前 |
![]() |
L. Fox · 我在这里用的是什么样的Laravel雄辩的关系 6 年前 |
![]() |
Geoff Harper · 我应该如何构建关系松散的SQL db 6 年前 |
![]() |
waroxx · SQL—当多个表具有相同的列时,最好怎么做 6 年前 |
![]() |
Lumpi01 · SQL 2不同的注释类型-最佳解决方案? 6 年前 |
![]() |
Hayreddin Tüzel · 预约系统数据库建模[关闭] 6 年前 |