我认为我应该被算作数据库新手,所以把这个问题当做一个新手问题来读。我目前创建了一个表,其中包含许多主机的环境变量,如下所示:
create table envs (
host varchar(255),
envname varchar(255),
envvalue varchar(8192),
PRIMARY KEY(host, envname)
);非常简单,一个表包含我需要的所有数据。常见的操作是获取给定主机的所有环境变量,另一个操作是获取给定主机的给定环境变量,第三个示例操作是获取所有主机的给定环境变量并列出重复项。
预计性能不会成为问题,可能会有数十台主机,每台主机上有几十个变量,平均每秒最多有1个查询。
现在我已经了解到,拥有复合主键并不一定是一个好主意。这对于上面的用例是真的吗?如果这是真的,我应该如何改变数据库设计?如果不是,那么上面的单表数据库是否可以满足我上面列出的目的?
发布于 2012-11-12 19:28:21
我看不出主键有什么问题。主键的语义是唯一地标识键值的非键属性值。因为我假设对于一个主机和一个envname,最多只有一个envvalue,所以主键非常有意义。
这可能是因为有些人反对组合主键,因为他们害怕性能问题。但是,性能方面的考虑永远不应该影响主键的选择。许多数据库系统会自动为主键创建索引结构;此索引结构的选择会影响性能。但是,这种选择大多可以手动更改,如果确实存在性能问题,则应该在以后进行更改。
您的单表设计和主键的选择很好。
发布于 2012-11-12 19:27:17
现在我已经了解到,拥有复合主键并不一定是一个好主意。这对于上面的用例是真的吗?
不是的。在(host, envname)上使用复合主键。
如果是真的,我应该如何更改数据库设计?
不适用。
如果不是,那么上面的单表数据库是否可以满足我上面列出的目的?
是的,它被称为Entity–Attribute–Value model。
发布于 2012-11-12 19:33:40
这不是一个好主意,因为您需要多次存储唯一的主机名(,envname) 。
如果将主机名从srv01更改为*srv01_new*,会发生什么情况?每次在表中出现srv01时,您都必须更改。如果有一天,您决定创建一个包含有关每个主机的附加信息的新表,该怎么办?
现在,如果您更改主机名,则必须同时更改这些信息。
回答你的问题:这不是performance的问题,而是normalization.的问题
数据库通常应该尽可能地规范化。如果你有足够的兴趣,read on。
您应该为您的主机创建一个表,将惟一的id (int)作为主键,将惟一的(索引)作为主机名。
然后,您的表应该只引用主机的id,而不是名称。这样,您的主机名只会在整个数据库中存储一次,并且可以更改为您想要的任何名称,而不会破坏其他表。
如果您的环境名称也是唯一的,那么您应该为这些环境名称创建另一个与主机表(id、name)具有相同布局的表。
然后,组合表存储主机的id和环境的id以及值。当然,您必须保留组合的主键,因此主机/环境的每个组合都是唯一的,并且很容易被索引。
然后,您就拥有了具有附加属性和完美规范化的多对多关系。
https://stackoverflow.com/questions/13342783
复制相似问题