2012-09-01 157 views
2

在我的数据库中,我有一个有关它们的信息的用户列表,而且我还有一个功能,允许用户将其他用户添加到候选列表中。我的用户信息存储在一个带有用户标识的主键的表中,并且我有另一个表作为候选列表。候选名单表的设计使其具有两列,基本上只是一对名称列表。因此,要找到特定用户的候选名单,可以从第二列中检索所有名称,其中第一列中的id是特定值。为什么我的数据库表需要一个主键?

问题是,根据许多来源,如这个Should each and every table have a primary key?你应该在数据库的每个表中有一个主键。

根据此来源http://www.w3schools.com/sql/sql_primarykey.asp - 一个唯一标识数据库中的条目的主键。所以我的问题是:

  1. 我的数据库中的表有什么问题?为什么它需要一个主键?

  2. 我该如何给它一个主键?只需创建一个新的自动递增列,以便每个条目都有一个唯一的ID?这似乎没有多少意义。或者,我会以某种方式将表示候选名单的多个条目封装到另一个表中的另一个实体中,并将​​其链接到?我很困惑。

+0

只用一个索引来尝试它,您不需要主键。获取性能没有的数字,看看它是否足够快。 –

+0

谢谢,我会尝试。然而,从适当的关系角度来看,你会如何去做这样的事情?这不像是你可以创建另一个表格来表示一个人的候选名单,因为这还需要适应这样一个事实,即我们不知道这个人会添加多少人。所以你不能为每一个单独列 - 你需要一个新的行 - 回到相同的情况哈哈! – user1058210

+0

您创建了一个具有两个用户标识作为列的表,因此您可以将某个人与其他人关联起来,并且如果要强制执行唯一性,请创建一个由两列组成的主键。 –

回答

2

如果这些行是唯一的,那么您可以拥有一个两列主键,尽管这可能与数据库有关。这里有一个例子:

CREATE TABLE my_table 
(
col_1 int NOT NULL, 
col_2 varchar(255) NOT NULL, 
CONSTRAINT pk_cols12 PRIMARY KEY (col_1,col_2) 
) 

如果你已经有了表,该例子是:

ALTER TABLE my_table 
ADD CONSTRAINT pk_cols12 PRIMARY KEY (col_1,col_2) 
+0

是的,我想每一行都是唯一的。你会这样做的方式是什么?我唯一能想到的另一种方式就是用我的用户信息表扩展入选的CSV值 - 虽然我不想这样做,因为搜索会很糟糕! – user1058210

+0

我添加了一个例子。我不确定这对于不同的数据库是多么便携。 – David

2

主键唯一地标识每个记录,因为它是前面提到的,主键可以由多个的属性(1列或更多列)。首先,我建议确保每个记录在您的表格中都是独一无二的。其次,据我所知,你离开表没有主键,这是不允许的,所以是的,你需要为它设置密钥。

2

在这种特殊情况下,在shortlist表中存储的同一对用户ID中不会有多次存储目的。毕竟,该表模拟一个集合,并且元素在集合中或者不在集合中。在集合中有一个“两倍”的元素没有意义。为了防止这种情况,请创建一个组合键,由这两个用户ID字段组成。

无论该组合键也将是主要的,或者你有另一个键(这将作为代理主键)是another matter,但无论哪种方式,你需要该组合键。

请注意,根据支持clustering (aka. index-organized tables)数据库,PK往往也是聚集键,这可能对性能显著反响。


不同于mutiset。

2

具有重复行的表不是关系的适当表示。这是一包行,而不是一组行。如果你让这种情况发生,你最终会发现你的计数将会被关闭,你的资金将会关闭,你的平均数将会被关闭。简而言之,当您使用它时,您会在数据中混淆错误。

声明主键是防止重复行进入数据库的一种便捷方式,即使其中一个应用程序出错。您获得的索引是一个副作用。

通过引用任何候选键可以创建对表中单个行的外键引用。但是,如果将这些候选键中的一个声明为主键,然后使所有外键引用都引用主键,则会更加方便。这只是谨慎的数据管理。

现实世界中的实体与表中该实体的对应行之间的一一对应关系超出了DBMS领域。这取决于您的应用程序,甚至是您的数据提供者通过不为现有实体创造新行并且不让某些新实体滑过这些裂缝来维护该对应关系。

1

既然你问了,这是好的做法,但在少数情况下(数据不需要连接),它可能不是绝对必需的。但最大的问题是,你永远不知道需求是否会改变,所以你现在真的想要一个,所以你没有在事实后添加一个到10米记录表.....

除了主键(它可以跨越多列顺便说一句)我认为这是一个很好的做法,有一个第二候选人的关键是一个单一的领域。这使联接更容易。

首先是一些理论。你可能还记得HS或者大学代数中函数的定义是:y = f(x)其中f是一个函数,当且仅当每个x有一个y。在这种情况下,在关系数学中,我们会说在这种情况下y是functionally dependent

您的数据也是如此。假设我们正在存储支票号码,检查账户号码和金额。假设我们可能有多个支票账户,并且对于每个支票账户不允许有重复支票号码,那么金额在功能上取决于(账户,支票号码)。一般而言,您希望将数据存储在一起,这些数据在功能上依赖于同一事物,而无需传递依赖关系。主键通常是您指定为主键的功能依赖关系。这然后识别行中的其余数据(因为它与该标识符相关联)。把它看作是natural primary key.尽可能(即不使用MySQL)我喜欢将主键声明为自然键,即使它横跨列。有时你可能有多个可互换的候选键,这会变得复杂。例如,考虑:

CREATE TABLE country (
    id serial not null unique, 
    name text primary key, 
    short_name text not null unique 
); 

此表真的可以有任何列作为主键。这三个都是完全可以接受的候选键。假设我们有一个国家记录(232,'美国','美国')。这些字段中的每一个都唯一标识记录,因此如果我们知道其中一个我们可以知道其他字段。每一个都可以被定义为主键。

我还建议拥有第二个人造候选键,它只是用于连接链接的机器标识符。在上面的例子中,country.id是这样做的。这对于将其他记录链接到国家/地区表格很有用。

需要候选关键字的例外情况可能是重复记录真的可能存在的地方。例如,假设我们正在跟踪发票。我们可能会有两个项目独立开具发票的情况,两个项目中的每一个都会显示一个项目。这些可能是相同的。在这种情况下,您可能希望添加一个人造主键,因为它允许您稍后将事物连接到该记录。你现在可能没有必要这样做,但你可能在将来!

相关问题