1

我认为我应该算作数据库新手,所以把这个问题当作一个新手问题来阅读。我目前创建了一个表,其中包含许多主机的环境变量,如下所示:

create table envs ( 
  host varchar(255), 
  envname varchar(255), 
  envvalue varchar(8192), 
  PRIMARY KEY(host, envname)
);

非常简单,一张表包含我需要的所有数据。常见操作是获取给定主机的所有环境变量,另一个是获取给定主机的给定环境变量,第三个示例操作是获取所有主机的给定环境变量并列出重复项。

性能预计不会成为问题,可能会有数十台主机,每台主机数十个变量,平均每秒最多 1 个查询。

现在我读到拥有复合主键不一定是个好主意。对于上述用例,这是真的吗?如果是真的,我应该如何更改数据库设计?如果不是,上述单表数据库是否适合我上面列出的用途?

4

3 回答 3

2

我在这里没有看到主键有问题。主键的语义是唯一标识键值的非键属性值。正如我假设对于一个主机和一个 envname 最多有一个 envvalue 主键非常有意义。

可能有些人反对复合主键,因为他们害怕性能问题。然而,性能考虑永远不应该影响主键的选择。许多数据库系统会自动为主键创建索引结构;这种索引结构的选择会影响性能。但是,此选择大多可以手动更改,如果您确实遇到性能问题,应该稍后再进行更改。

您的单表设计和主键选择很好。

于 2012-11-12T11:28:21.317 回答
1

现在我读到拥有复合主键不一定是个好主意。对于上述用例,这是真的吗?

否。在 上使用复合主键(host, envname)

如果是真的,我应该如何更改数据库设计?

不适用。

如果不是,上述单表数据库是否适合我上面列出的用途?

是的:它被称为实体-属性-值模型

于 2012-11-12T11:27:16.670 回答
1

这是一个坏主意,因为您多次存储唯一(主机、环境名称)。

如果您要将主机名从srv01更改为 *srv01_new* 会怎样?您必须更改表中 srv01 的每一次出现。如果有一天,您决定需要创建一个新表来保存有关每个主机的附加信息,该怎么办。

现在,如果您更改主机名,您也必须更改这些信息。

回答您的问题:这不是性能问题,而是规范化问题。

数据库通常应尽可能标准化。如果您足够感兴趣,请继续阅读

您应该为您的主机创建一个表,将唯一的id (int) 作为主键,并将唯一的(索引)名称作为主机名。

然后,您的表应该只引用主机的id,而不是name。这样,您的主机名仅在整个数据库中存储一次,并且可以更改为您想要的任何内容,而不会破坏其他表。


如果您的环境名称也是唯一的,您应该为它们创建另一个表,其布局与主机表(id、名称)相同。

然后,您的组合表存储主机id 和 environment的 id以及值。您当然必须保留组合的主键,因此主机/环境的每个组合都是唯一的并且易于索引。

然后,您将拥有具有附加属性和完美规范化的多对多关系。

于 2012-11-12T11:33:39.770 回答