我在一些表中进行了一些测试,这些表有超过1M的记录,并且运行ALTER TABLE语句来添加/删除各种列类型将在我的测试机器上花费大约13秒,所以我想知道这是不是很好替代EAV模型?
我在几个M记录上进行测试的原因是因为我的具体用例,我不认为每个动态创建的表都有超过5M的记录,但是我&#39 ; ll有几百个表,字段将被搜索很多。我也不认为田地会经常改变。
是否有人使用此工作流程动态地将列添加到表格中,与EAV模型相反?如果是这样,它如何比较?
感谢。
答案 0 :(得分:0)
将ALTER TABLE
用于EAV(又名"可扩展字段","自定义字段"等)总是一个坏主意。虽然在大多数情况下,将新的NULL
列添加到现有表中并不是一个过于昂贵的操作,但是列的删除,重新排序和非追加插入非常昂贵 - 通常需要将所有数据复制到一个新的目标表并删除原始目录(必须在事务中完成,通常使用表级锁定),不要忘记删除和重新创建外键约束。
理想情况下,EAV数据应存储在专用EAV数据库系统中,该系统可处理稀疏数据并强制执行EAV所需的特殊约束(例如,限制给定类型的父实体或其他业务规则允许哪些EAV属性)。通常,这是通过NoSQL或文档存储数据库(例如MongoDB)完成的。
但是,如果您唯一的工具是MySQL并且您无法运行其他类型的服务器,那么您最好采用实际的EAV模式来存储您的数据,例如下面的内容(伪代码SQL) ):
CREATE TABLE Attributes (
AttributeId bigint IDENTITY(1,1) PRIMARY KEY
Name nvarchar(50),
Type smallint /* some enum you define */
)
CREATE TABLE AttributeHolders (
HolderId bigint IDENTITY(1,1) PRIMARY KEY
)
CREATE TABLE AttributeValues (
HolderId bigint FK AttributeHolders.HolderId,
AttributeId bigint FK Attributes.AttributeId,
TextValue nvarchar(100) NULL,
IntValue bigint NULL,
DateValue datetimeoffset NULL
)
然后,您需要从其他实体表中向AttributeHolders.HolderId
添加FK,并添加一个约束,以防止这些实体的不同实例共享相同的HolderId
。
......这是留给读者的问题。遗憾的是,没有简单的跨平台解决方案。虽然有一个选项是创建一个SEQUENCE
对象,该对象充当可以Holders
的各种实体的标识值源。