FK:PK关系如何在Sqlite中运行?

时间:2018-04-06 19:26:58

标签: sqlite foreign-keys

我正在使用DB浏览器来尝试解决这个问题。我已经打开了Northwind.sqlite,在其中它显示了以下表格:

CREATE TABLE `Order Details` (
    `OrderID`   int,
    `ProductID` int,
    `UnitPrice` float ( 26 ),
    `Quantity`  int,
    `Discount`  float ( 13 ),
    PRIMARY KEY(`OrderID`,`ProductID`)
);

但是,在Sql Server中,Northwind OrderID和ProductID是外键,而不是主键。这在SQLite中有何不同?如果是这样,关系如何运作?

谢谢 - 戴夫

1 个答案:

答案 0 :(得分:1)

以上将创建一个没有FOREIGN键但有2个索引的表。

  • 根据 rowid ,这是一个很大程度上隐藏的索引。

  • 另一个,PRIMARY KEY(订单ID ,产品ID )将是 OrderId ProductID 组合的索引强>

关于rowid的一些事情(又名id)

  • rowid 是一个名为 rowid 的自动创建的列(也可以使用 oid rowid来引用 em> (与案例无关))如果存在则确实是主键。
  • rowid 将是一个唯一的有符号整数,最多64位。最低值和第一个值将 1 ,最高值为 9223372036854775807
  • 在SQLT 3.8.2的更高版本中,添加了WITHOUT ROWID关键字以允许抑制 rowid 列/索引(您的订单明细表可能有利于没有rowid表)。
  • 如果使用类型INTEGER PRIMARY KEYINTEGER PRIMARY KEY AUTOINCREMENT定义列,则该列(每个表只能有1个此类列)是 rowid 的别名柱。
    • AUTOINCREMENT引入了一条规则,即插入行时rowid必须大于任何存在或存在的行。
    • 它并不保证 rowid 会单调增加,尽管通常会有id(即使没有AUTOINCREMENT(可能是SQLite中最误用/误解的关键字))。
    • 没有AUTOINCREMENT SQlite可能会找到较低的 rowid 并使用它,但直到达到 9223372036854775807 rowid 为止。
    • AUTOINCREMENT,如果已达到 9223372036854775807 rowid ,则为SQLITE_FULL异常。
    • AUTOINCREMENT导致开销(例如,一个名为sqlite_sequence的表保持记录最高的给定序列号)。文档建议除非需要,否则不要使用它,这种情况很少发生。
    • 我做的一些有限的测试导致AUTOINCREMENT的处理时间增加了8-12%。 What are the overheads of using AUTOINCREMENT for SQLite on Android?
    • 有关 rowid 的详情,请参阅SQLite Autoincrement以及Clustered Indexes and the WITHOUT ROWID Optimization

编码PRIMARY KEY(如果不在INTEGER列上,即不是 rowid的别名),则表示UNIQUE约束。它并不是说/检查聚集索引中的值或任何值是否存在于任何其他表中。

  • 注意null不被视为相同的值,因此在Order Details表中,可以将值的任意组合设为null。

编码FOREIGN KEY引入了一个约束,即所引用的值必须存在于相应的表/列中。另外: -

  

通常,外键约束的父键是主键   父表的。如果它们不是主键,则为父键   键列必须共同使用UNIQUE约束或   有一个独特的索引。如果父键列具有UNIQUE索引,   然后该索引必须使用在中指定的归类序列   父表的CREATE TABLE语句。   SQLite Foreign Key Support

考虑到所有这些,您可能希望对Order Details表进行一些更改: -

  • 您可以将其设为WITHOUT ROWID表。
  • 您可以将OrderIDProductID列设为NOT NULL。
  • 您可以为OrderIDProductID列添加FOREIGN KEY。

所以也许你可以: -

CREATE TABLE `Order Details` (
    `OrderID`   int NOT NULL REFERENCES `Orders` (`OrderId`), -- ADDED NOT NULL and FKEY
    `ProductID` int NOT NULL REFERENCES `Products`(`ProductId`) , -- ADDED NOT NULL and FKEY
    `UnitPrice` float ( 26 ),
    `Quantity`  int,
    `Discount`  float ( 13 ),
    PRIMARY KEY(`OrderID`,`ProductID`)
    )
    WITHOUT ROWID -- ADDED WITHOUT ROWID
;
  • 以上使用列约束

或者,利用TABLE约束,您可以: -

CREATE TABLE `Order Details` (
    `OrderID`   int NOT NULL, -- ADDED NOT NULL
    `ProductID` int NOT NULL, -- ADDED NOT NULL
    `UnitPrice` float ( 26 ),
    `Quantity`  int,
    `Discount`  float ( 13 ),
    PRIMARY KEY(`OrderID`,`ProductID`),
    FOREIGN KEY (`OrderId`) REFERENCES `Orders`(`OrderId`), -- ADDED FKEY AS TABLE CONSTRAINT
    FOREIGN KEY (`ProductID`) REFERENCES `Products`(`ProductID`) -- ADDED FKEY AS TABLE CONSTRAINT
    )
    WITHOUT ROWID -- ADDED WITHOUT ROWID
;

两者都有相同的结果,唯一的区别是定义了FOREIGN KEY约束。

以上两者均假设引用的表格为OrdersProducts