我有几个表,例如Buyers
,Shops
,Brands
,Money_Collectors
,e.t.c。
其中每一个都有一个默认值,例如默认Buyer
为David
,默认Shop
为Ebay
,依此类推。
我想将这些默认值保存在数据库中(以便用户可以更改它们)。
我想在每个表中添加is_default
列,但它似乎无效,因为每个表中只有一行可能是默认值。
然后我认为最好的是Defaults
表将包含所有默认值。该表将包含1行和N列,其中N是默认值的数量:
Defaults table:
buyer shop brand money_collector
----- ---- ----- ---------------
David Ebay Dell NULL (no default value)
但是,这似乎不是最好的方法,因为在添加新的默认值时表结构会发生变化。
存储默认值的最佳方法是什么?
答案 0 :(得分:19)
要明确。
最好的方法是在每个表上都有一个列来自下拉源。
这就是为什么......
“我不应该担心空间 将数据保存在数据库中?“
简短的回答是否定的。更长的答案是你应该担心的是性能。专注于太空将导致你做很糟糕的事情。
如果考虑空间,你会做的坏事。
假设有50家商店(选择框) 有50个可能的值)。在这 案例,存储您的默认商店 需要50个布尔字段,
这是 ONE 布尔列。它存在于每一行。
我问你这个问题。如果您创建了一个包含1个日期列并插入1行的表,那么您在磁盘上将使用多少空间?
如果您说7或8个字节,那么您将关闭大约1000次。
磁盘空间的最小单位是块。块是典型的8kb(可以小到2kb,大到32kb,一般(这里没有挑剔,实际限制是不重要的))
假设您有8kb块然后是1列,1行表需要8Kb。如果你插入另外999行,它仍然会占用8KB。 (同样没有挑剔每个块和每行的开销 - 这是一个例子)
因此,在具有50个商店名称的查找表中,向表格大小添加50个字节的可能性迫使您从1个区块扩展到2个区域,这种可能性很小甚至完全不相关。
另一方面,您的默认表肯定会占用至少一个额外的块。 但是对于 PERFORMANCE 最严重的打击是你填写下拉列表的调用将需要两次往返数据库,一次获取列表,一次获取默认值。 (是的,您可以在一个中执行此操作,但可以使用它)
因此,您节省了零空间并使网络流量增加了一倍。
你看到我在说什么。
停止担心空间的另一个关键理由是你放弃了清晰度。想想你将要雇用的开发人员来运行这个应用程序。当他加入团队并查看数据库时,想象两种情况。
你要求他用'商店'的下拉列表建立一个新的for。
在方案1中,他找到了商店表,将下拉列表连接到表的简单查询,并使用default_value字段选择初始值。
在方案2中,如果没有经过一些培训,他怎么知道寻找一个单独的表?也许他会看到桌子,但到你招聘的时候,你的数据模型现在有数百张桌子。
再次,有点做作,但重点是显着。数据库中的清晰度很好,每行值得一个字节。
技术资料
我不是MySQL人,但在Oracle中,行末的空列不占用额外空间。在Oracle中我会使用Varchar2(1)并让'T'= Default并将其他人保留为null。这将仅对1个加法字节总数产生影响,而不是每行。 YMMV与MySQL,你可以单独提出这个问题,如果你不能谷歌答案。
但是,担心这个问题的时间是数百万行,而不是数百行。任何提供下拉列表的表都不会大到开始担心额外的字节。
答案 1 :(得分:1)
如果您创建XML然后将该XML存储在XML列的表中,该怎么办? XML列包含XML,XML可以包含表的标记和默认值的子节点。
答案 2 :(得分:0)
您应该创建一个包含两列和n行
的表Defaults table:
buyer, David
shop, Ebay,
brand, Dell
这样您就可以添加新值而无需更改表结构
答案 3 :(得分:0)
您可以创建目录表(某种元数据表),其中包含所需表格列的默认值作为字符串。然后,您可以使用转换函数来获取适当的值。下面是一个示例表定义(使用了Transact-SQL ):
create table dbo.cat_default_values
(
id_column varchar(30) not null,
id_table varchar(30) not null,
datatype varchar(30) not null,
value varchar(100) not null,
f_creation datetime not null,
usr_creation char(8) null,
primary key clustered (id_column, id_table)
)
declare @defaultValueInt int,
@defaultValueVarchar varchar(30)
select @defaultValueInt = convert(int, value)
from cat_default_values where id_column = "defColumInteger" and id_table = "table1"
select defaultValueVarchar = value
from cat_default_values where id_column = "defColumVarchar" and id_table = "table1"
答案 4 :(得分:0)
您要存储的内容不是元数据信息。首先,我不会发明一个外部数据存储来存储这些数据。(加上额外的代码)
我假设你有一个PK序列生成逻辑(在你的控制之下)。我将分配一个幻数x,我将在每个表中插入一条记录,其中_id = x作为默认值。因此,如果要向用户显示默认值,可以以统一的方式处理查询,也可以在插入时在应用程序逻辑中处理。关于这一点的好处是,您可以一直访问默认值而无需编写任何额外的逻辑,并且可以使用相同的代码维护用于维护表的默认值的逻辑(模板;) (摘自W3c从使用DTD建模XML模式信息中学到的经验教训。)
唯一的问题是这个逻辑应该使用一些广泛的文档来明确,或者可能通过使用触发器来强制执行。