SQLITE继承或如何解决多个外键
SQLITE inheritance or how to solve multiple foreign keys
我已经看到了多种解决方案,但它们似乎并不完全适合我的情况,或者至少我仍然希望有更好的解决方案。
在我的数据库中有下表“地方”、“动物”和“人”。目前我有表“hasAnimal”和“hasPeople”,但多态方法“hasBeing”会更合理。但是我想 link foreign-keys;但不能 link 两个外键 - 据我所知。
如何解决多态问题?
我不太了解数据库,所以解决方案可能很明显。
我现在将添加更多信息,以防我写的 question/explanation 没有包含足够的信息
CREATE TABLE "persons" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
"firstname" TEXT NOT NULL,
"surename" TEXT
)
CREATE TABLE "animals" (
"name" TEXT NOT NULL UNIQUE,
"description" TEXT NOT NULL,
"movementLocations" INTEGER NOT NULL,
"movementPlaces" INTEGER,
"groupsize" INTEGER NOT NULL,
"link" TEXT,
PRIMARY KEY("name")
)
CREATE TABLE "places" (
"name" TEXT NOT NULL UNIQUE,
"description" TEXT NOT NULL,
PRIMARY KEY("name")
)
CREATE TABLE "hasPerson" (
"id" TEXT NOT NULL,
"place" TEXT NOT NULL,
FOREIGN KEY("id") REFERENCES "persons"("id"),
FOREIGN KEY("place") REFERENCES "places"("name"),
PRIMARY KEY("id","place")
)
CREATE TABLE "hasAnimal" (
"name" TEXT NOT NULL,
"place" TEXT NOT NULL,
PRIMARY KEY("name","place"),
FOREIGN KEY("name") REFERENCES "animal"("name")
)
而wouldbe-table(存在就是动物和人的parent)
CREATE TABLE "hasBeing" (
"name" TEXT NOT NULL,
"place" TEXT NOT NULL,
PRIMARY KEY("name","place"),
FOREIGN KEY("name") REFERENCES "animal"("name") OR "person"("id")
)
为什么我认为使用“hasBeing”更好?
这样一来,我就不会使用两个表格来描述一个人在某个地方,而是可以使用一个表格来代替。为了让所有众生都在一个地方,我不再需要 运行 通过 2 个表。如果“将属于一起的东西放在一起并合并相似的关系是好的”假设是错误的,我将接受解释作为答案并重新表述问题。
您的 has* table 称为 Link table,因为它们 link 是您数据库中的两个实体。如果将一个实体 link 编辑到另外两个实体,则其他每个实体都需要一个 FKey,就像您在原始实体中那样。
现在你引入了一个新的实体:一个存在,但只是作为一个 link 并且没有实际的存在实体。这不是一个好的设计。您最好使用原始版本或:
hasBeing 将人名和动物名作为单独的可为空
列,FK 到他们的 tables,两个名字之一将
始终为空。
将人和动物合二为一table,用一个标志表示什么
每行代表的实体种类。 (这不是一个好主意,因为没有
两者之间的数据有很多共性,但它可能是一个有用的
技术。)
原来的方式可能是最好的,而且并不罕见。请记住,关系型 数据库不是面向对象的,多态性不是一个合适的目标。
我已经看到了多种解决方案,但它们似乎并不完全适合我的情况,或者至少我仍然希望有更好的解决方案。
在我的数据库中有下表“地方”、“动物”和“人”。目前我有表“hasAnimal”和“hasPeople”,但多态方法“hasBeing”会更合理。但是我想 link foreign-keys;但不能 link 两个外键 - 据我所知。
如何解决多态问题?
我不太了解数据库,所以解决方案可能很明显。
我现在将添加更多信息,以防我写的 question/explanation 没有包含足够的信息
CREATE TABLE "persons" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
"firstname" TEXT NOT NULL,
"surename" TEXT
)
CREATE TABLE "animals" (
"name" TEXT NOT NULL UNIQUE,
"description" TEXT NOT NULL,
"movementLocations" INTEGER NOT NULL,
"movementPlaces" INTEGER,
"groupsize" INTEGER NOT NULL,
"link" TEXT,
PRIMARY KEY("name")
)
CREATE TABLE "places" (
"name" TEXT NOT NULL UNIQUE,
"description" TEXT NOT NULL,
PRIMARY KEY("name")
)
CREATE TABLE "hasPerson" (
"id" TEXT NOT NULL,
"place" TEXT NOT NULL,
FOREIGN KEY("id") REFERENCES "persons"("id"),
FOREIGN KEY("place") REFERENCES "places"("name"),
PRIMARY KEY("id","place")
)
CREATE TABLE "hasAnimal" (
"name" TEXT NOT NULL,
"place" TEXT NOT NULL,
PRIMARY KEY("name","place"),
FOREIGN KEY("name") REFERENCES "animal"("name")
)
而wouldbe-table(存在就是动物和人的parent)
CREATE TABLE "hasBeing" (
"name" TEXT NOT NULL,
"place" TEXT NOT NULL,
PRIMARY KEY("name","place"),
FOREIGN KEY("name") REFERENCES "animal"("name") OR "person"("id")
)
为什么我认为使用“hasBeing”更好? 这样一来,我就不会使用两个表格来描述一个人在某个地方,而是可以使用一个表格来代替。为了让所有众生都在一个地方,我不再需要 运行 通过 2 个表。如果“将属于一起的东西放在一起并合并相似的关系是好的”假设是错误的,我将接受解释作为答案并重新表述问题。
您的 has* table 称为 Link table,因为它们 link 是您数据库中的两个实体。如果将一个实体 link 编辑到另外两个实体,则其他每个实体都需要一个 FKey,就像您在原始实体中那样。
现在你引入了一个新的实体:一个存在,但只是作为一个 link 并且没有实际的存在实体。这不是一个好的设计。您最好使用原始版本或:
hasBeing 将人名和动物名作为单独的可为空 列,FK 到他们的 tables,两个名字之一将 始终为空。
将人和动物合二为一table,用一个标志表示什么 每行代表的实体种类。 (这不是一个好主意,因为没有 两者之间的数据有很多共性,但它可能是一个有用的 技术。)
原来的方式可能是最好的,而且并不罕见。请记住,关系型 数据库不是面向对象的,多态性不是一个合适的目标。