我有一个sqlite数据库,结构如下:
CREATE TABLE IF NOT EXISTS Patient
( PatientId INTEGER PRIMARY KEY AUTOINCREMENT );
CREATE TABLE IF NOT EXISTS Event
(
PatientId INTEGER REFERENCES Patient( PatientId ),
DateTime TEXT,
EventTypeCode TEXT,
PRIMARY KEY( PatientId, DateTime, EventTypeCode )
);
CREATE TABLE IF NOT EXISTS Reading
(
PatientId INTEGER REFERENCES Patient( PatientId ),
DateTime TEXT REFERENCES Event (DateTime),
EventTypeCode TEXT REFERENCES Event (EventTypeCode),
Value REAL,
PRIMARY KEY( PatientId, DateTime, EventTypeCode )
);
我插入患有Id#1的患者
然后我跑:
INSERT INTO Event (PatientId, DateTime, EventTypeCode) VALUES (1, '2011-01-23 19:26:59', 'R')
哪个有效
然后我跑:
INSERT INTO Reading (PatientId, DateTime, EventTypeCode, Value) VALUES (1, '2011-01-23 19:26:59', 'R', 7.9)
它给了我一个外键不匹配。在所有情况下,患者ID均为“1”,日期时间和类型代码在第2次和第3次查询中匹配。我不明白什么是不匹配的,但我实际定义外键有点新,我不知道我做错了什么。
答案 0 :(得分:35)
我对SQLite不熟悉,但对Google turned up this有点兴趣。文档说
如果数据库架构包含 需要的外键错误 看着不止一张桌子 识别的定义,然后是那些 当没有检测到错误 表已创建。相反,这样 错误阻止了应用程序 准备修改的SQL语句 孩子或父母的内容 表格使用外国的方式 键。内容出现时报告的错误 改变了“DML错误”和错误 模式更改时报告 是“DDL错误”。所以,换句话说, 配置错误的外键约束 需要同时看着孩子 和父是DML错误。 英语 外键的语言错误消息 DML错误通常是“外键” 不匹配“但也可以”没有这样的 表“如果父表没有 存在。外键DML错误可能是 是 报道如果:
- 父表不存在,或
- 外键约束中指定的父键列不存在, 或
- 外键约束中指定的父键列不是 父表的主键和 不受限制 使用中指定的整理顺序 CREATE TABLE,或
- 子表不引用父表的主键 指定主键列和 中的主键列数 父母的数量不匹配 子键列。
我怀疑你可能会在该列表中遇到#3。
此外,虽然其他数据库可能支持使用非唯一索引作为外键引用(see answers here),但在我看来,这是一个糟糕的设计选择。我会重组以便
Reading.PatientId
引用Event.PatientId
,以便Event
引用Reading
中的完整复合键,或EventId
自动增量主键添加到Event
表,并将其用作Reading
表中的外键(这样您只有EventId
以及Value
下的Reading
,您可以PatientId, DateTime, EventTypeCode
获取Event
。我建议#2,以便您可以避免PatientId, DateTime
和EventTypeCode
中Event
和Reading
的冗余。