在数据库中存储默认值的最佳方法是什么?

时间:2011-01-12 11:14:26

标签: mysql database database-design default-value

我有几个表,例如BuyersShopsBrandsMoney_Collectors,e.t.c。

其中每一个都有一个默认值,例如默认BuyerDavid,默认ShopEbay,依此类推。

我想将这些默认值保存在数据库中(以便用户可以更改它们)。

我想在每个表中添加is_default列,但它似乎无效,因为每个表中只有一行可能是默认值。

然后我认为最好的是Defaults表将包含所有默认值。该表将包含1行和N列,其中N是默认值的数量:

Defaults table:

buyer      shop      brand      money_collector
-----      ----      -----      ---------------
David      Ebay      Dell       NULL   (no default value)

但是,这似乎不是最好的方法,因为在添加新的默认值时表结构会发生变化。

存储默认值的最佳方法是什么?

5 个答案:

答案 0 :(得分:19)

要明确。

最好的方法是在每个表上都有一个列来自下拉源。

这就是为什么......

  

“我不应该担心空间   将数据保存在数据库中?“

简短的回答是否定的。更长的答案是你应该担心的是性能。专注于太空将导致你做很糟糕的事情。

如果考虑空间,你会做的坏事。

  • 你会将意思埋葬在主键中。即智能钥匙。
  • 您将尝试将多个值存储在一列中。
  • 你的索引太少
  • (毫无疑问,我们可以创建50个节省空间的不良做法列表)
  

假设有50家商店(选择框)   有50个可能的值)。在这   案例,存储您的默认商店   需要50个布尔字段,

这是 ONE 布尔列。它存在于每一行。

我问你这个问题。如果您创建了一个包含1个日期列并插入1行的表,那么您在磁盘上将使用多少空间?

如果您说7或8个字节,那么您将关闭大约1000次。

磁盘空间的最小单位是块。块是典型的8kb(可以小到2kb,大到32kb,一般(这里没有挑剔,实际限制是不重要的))

假设您有8kb块然后是1列,1行表需要8Kb。如果你插入另外999行,它仍然会占用8KB。 (同样没有挑剔每个块和每行的开销 - 这是一个例子)

因此,在具有50个商店名称的查找表中,向表格大小添加50个字节的可能性迫使您从1个区块扩展到2个区域,这种可能性很小甚至完全不相关。

另一方面,您的默认表肯定会占用至少一个额外的块。 但是对于 PERFORMANCE 最严重的打击是你填写下拉列表的调用将需要两次往返数据库,一次获取列表,一次获取默认值。 (是的,您可以在一个中执行此操作,但可以使用它)

因此,您节省了零空间并使网络流量增加了一倍。

你看到我在说什么。


停止担心空间的另一个关键理由是你放弃了清晰度。想想你将要雇用的开发人员来运行这个应用程序。当他加入团队并查看数据库时,想象两种情况。

  1. 有一个名为Default_value
  2. 的布尔列
  3. 有一个表与任何名为Default_Values
  4. 的东西没有任何关系

    你要求他用'商店'的下拉列表建立一个新的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模式信息中学到的经验教训。)

唯一的问题是这个逻辑应该使用一些广泛的文档来明确,或者可能通过使用触发器来强制执行。