多列可以算作一个组合的主键吗?

时间:2018-09-15 09:47:47

标签: sqlite primary-key

在一个村庄里,村民们参观了许多房屋。我想存储哪个村民访问哪个房屋,以及他们访问房屋的频率。我决定按如下方式创建表格;

CREATE TABLE 'visitis'('villager' TEXT NOT NULL, 'house' INTEGER NOT NULL, 'amount' INTEGER NOT NULL DEFAULT 0);

该表存储如下;

  • villager存储村民的名字。每个村民都有一个唯一的名字。
  • house是房子的地址。这是一个整数。
  • amount存储该村民去过那所房子的次数。

该表不包含主键,因此,我认为它不是最佳的。村民的数量和房屋的数量都未定义到这样的水平,即将村民或房屋存储​​为一列不再有效。

多行可能包含相同的村民姓名,多行可能包含相同的房屋地址。唯一已知的唯一性是,村民与房屋的组合是唯一的。因此,我想知道是否有一种方法可以将两列用作共享主键。这样可以节省很多时间,但是我不确定SQLite是否能够执行此操作。 如果没有,是否有更好的方法来做到这一点?我有条件;

  1. 大多数村民将参观多所房屋。但是,这个数目相对较小,可以假定为少于50栋房屋;
  2. 有很多房屋(整数)将不被访问。但是, 造访过的房屋经常会被最多10个村民造访;
  3. 村民将参观数量有限的房屋,但只有少数参观超过1000所房屋;
  4. 重要的是存储哪个村民去哪个房子的频率;
  5. 经常需要通过村民的姓名和房屋的地址来访问数据;
  6. 房屋和村民的数量都可以很高。

也许我缺少明显明显的东西。我是...吗?

1 个答案:

答案 0 :(得分:2)

此表的主键似乎是villagerhouse列的组合。 SQLite的主键由多个列组成,没有问题:

CREATE TABLE visitis (
    villager TEXT NOT NULL,
    house INTEGER NOT NULL,
    amount INTEGER NOT NULL DEFAULT 0,
    PRIMARY KEY (villager, house)
);

这样做的逻辑原因是,访问特定房屋的特定村民仅需由一条记录代表。 amount列处理的情况是访问可能不止一次。

但是,尽管这解决了您眼前的问题,但这并不理想,因为您的表没有被规范化。 visitis表通常称为联结表,因为它以某种有意义的方式连接了其他两个表。这是一个更好的设计:

CREATE TABLE visitis (
    villager_id INTEGER NOT NULL,
    house_id INTEGER NOT NULL,
    amount INTEGER NOT NULL DEFAULT 0,
    PRIMARY KEY (villager_id, house_id),
    FOREIGN KEY (villager_id) REFERENCES villages (id),
    FOREIGN KEY (house_id) REFERENCES houses (id)
);

现在,我们只保留外键对,每个外键都指向villageshouses表中的一条记录。这样,我们就不会重复任何数据。