【问题标题】:SQLite table with two FKs, but only one at a time具有两个 FK 的 SQLite 表,但一次只有一个
【发布时间】:2014-07-19 00:21:42
【问题描述】:

我一直在为一个问题苦苦挣扎。非常感谢您的帮助。

这里是:

我有两个数据结构,ObjClass 和 Obj,其中 Obj 是 ObjClass 的一个特化。一个 Obj 可能有多个“插槽”,每个插槽都有自己的类型。 一个 Obj 拥有的总 Slots 是他自己的 Slots 与他的 ObjClass 的 Slots 的并集。这是简化的架构(如果有语法错误,请耐心等待):

create table ObjClass(
    ObjClassId integer not null primary key
)

create table Obj(
    ObjId integer not null primary key,
    ParentClass integer,

    foreign key(ParentClass) references ObjClass(ObjClassId)
)

create table Slot(
    SlotId integer not null primary key,
    SlotType integer
)

我要问的是:Slot 表与 ObjClass 或 Obj 有 1-n 关系,但绝不会两者兼而有之。如何在 SQLite 上执行此操作?

P.S.:我猜这个问题可能是由糟糕的数据库设计引起的。对于如何以更好的设计实现类似结构的任何想法也表示赞赏。

谢谢!

【问题讨论】:

  • 您对插槽的使用可能是一种反模式,EAV。
  • 第一条评论:这个问题是特定于 SQLite 的,并且没有一个答案考虑到这一点(即:考虑到这里使用的技术,它们不适用)第二条评论:可能是,但这并不能回答问题。
  • 第一。什么让你有那个想法?插槽=设置。第二。只是想你可能想知道。为什么还有呢?
  • 第一个:我的错误。当我没有找到关于 SQLite 检查约束的文档时,我认为它不支持它们。现在我知道它确实如此,它就像一个魅力。谢谢。 2nd:猜猜我只是粗鲁。对不起。

标签: sql sqlite foreign-keys


【解决方案1】:

你可以有两个 FK 都指向 ObjClassObj 喜欢

create table Slot(
    SlotId integer not null primary key,
    SlotType integer,
    FKColumn integer,
    foreign key(SlotType) references ObjClass(ObjClassId),
    foreign key(FKColumn) references Obj(ObjId)
)

编辑:

将与Obj/ObjClass 的关系转换为单独的中间表。创建一个引用所有 3 个表的中间表,如下所示。这样,您将与每个插槽的 ObjClass/Obj 关联。

create table SlorforeachObjandObjClass(
    SlotId integer,
    ObjClassId integer,
    ObjId integer, 
    foreign key(ObjClassId) references ObjClass(ObjClassId),
    foreign key(ObjId) references Obj(ObjId),
    foreign key(SlotId) references Slot(SlotId)
) 

【讨论】:

  • 但是不会强制执行引用的唯一性。我要问的是,如果 Slot 指向 Obj,那么 ObjClass 的任何 FK 都应该为 NULL。顺便说一句, SlotType 列不是参考,它只是插槽的标识符。我没有在那里放任何 FK,所以它不会影响答案。这种关系更像是“ObjClass/Obj has a Slot”而不是“Slot is an ObjClass/Obj”。
  • 对不起,在整理之前确认了评论。已编辑。
  • 我做到了。引用:“我要问的是:Slot 表与 ObjClass 或 Obj 有 1-n 关系,但从不两者。我如何在 SQLite 上强制执行此操作?”。编辑也无济于事,因为(我再次引用)“一个 Obj 可能有 多个“插槽”,每个都有自己的类型”。顺便说一句,谢谢你的帮助,我知道我不是很容易相处。
  • 我从中得到的是:如果另一个 FK 有值,则根本无法强制一个 FK 必须为 NULL(也就是说,不接受两个 FK 上都有值的记录) ?我必须在应用程序代码中强制这样的约束吗?
  • 现在我明白了。是的,这必须通过应用程序代码强制执行,或者您也可以使用插入前触发器(如果 SQLite 支持;我不确定)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
  • 2020-03-04
  • 1970-01-01
相关资源
最近更新 更多