【问题标题】:Apply foreign key and check constraint to MySQL table将外键和检查约束应用于 MySQL 表
【发布时间】:2020-01-16 18:46:25
【问题描述】:

我的问题归结为“连接表 B 是否会受到针对表 A 中不是外键的值的检查约束?”。对同一个外键的多次引用可能会使情况更加复杂。下面详细介绍了我正在努力解决的具体场景,并使用了一些缩写的 MySQL 代码。

MySQL 数据库包含表“Disorder”(如下所示):

CREATE TABLE `Disorder` (
disorder_name VARCHAR(255),
disorder_type VARCHAR(10),
PRIMARY KEY(`disorder_name`)
)

疾病类型可以是“综合征”或“疾病”。疾病和证候可以以多对多的方式联系起来(例如,几种疾病可以引起同一种证候,同一种疾病可能引起不同的证候)。

我希望创建一个名为“DiseaseSyndromeLink”的连接表,显示“疾病”和“综合征”疾病之间的关系。

CREATE TABLE `DiseaseSyndromeLink` (
`ds_id` int NOT NULL AUTO_INCREMENT,
    `disease` VARCHAR(255) NOT NULL,
`syndrome` VARCHAR(255) NOT NULL,
    PRIMARY KEY (`ds_id`),
    FOREIGN KEY (disease) REFERENCES disorder(disorder_name),
    FOREIGN KEY (syndrome) REFERENCES disorder(disorder_name)
)

此表需要难以设计的约束:

  • 第一列是整数连接ID

  • 第二列“疾病”是引用 Disorder.disorder_name 的外键。此处只允许输入 Disorder.disorder_type='Disease' 的 disorder_names。

  • 第三列“综合征”是引用 Disorder.disorder_name 的外键。此处只允许输入 Disorder.disorder_type='Syndrome' 的 disorder_names。

我觉得语法应该是这样的:

CREATE TABLE `DiseaseSyndromeLink` (
`ds_id` int NOT NULL AUTO_INCREMENT,
`disease` VARCHAR(255) NOT NULL,
`syndrome` VARCHAR(255) NOT NULL,
PRIMARY KEY (`ds_id`),
FOREIGN KEY (disease) REFERENCES disorder(disorder_name) WHERE (Disorder.disorder_type='Disease'),
FOREIGN KEY (syndrome) REFERENCES disorder(disorder_name) WHERE (Disorder.disorder_type='Syndrome')
)    

我的理解是检查值(例如 ='Disease')需要检查约束,而链接到原始表需要外键约束。我找不到同时使用这两个约束的任何文档或 YouTube 教程。由于很难找到此代码的任何示例,我想知道我是否在数据库设计方面犯了错误,但想不出一个好的替代方案。

这样可以同时使用检查和外键约束吗?

感谢您的宝贵时间!

问题已编辑为最初包含的有关试图在 DJANGO 方面加强这种关系的信息。

【问题讨论】:

    标签: mysql foreign-keys constraints check-constraints


    【解决方案1】:

    我看到您的 MYSQL 语句有点工作,所以您需要做的就是以与您一样的方式将外键添加到模型中。虽然这一次,您将设置 'null=True',如果您有唯一值,则 'unique=True' 这将处理空列。现在您必须在添加数据时在应用程序逻辑中实现休息,您必须知道“疾病类型在哪里”等标准。但是当你从数据库中读取时,Django 会自动预取相关的。读取数据的示例查询。

    data=Diseasesyndromelink.objects.filter(disease__feild="query")
    print(data.disease) #your foreign key object is prefetched here already.
    

    查看文档以获取更多示例。 https://docs.djangoproject.com/en/3.0/topics/db/models/

    【讨论】:

    • 您好,感谢您的意见!关于这个抱歉有点不清楚 - 您是建议过滤选择,然后在模型中使用这些选择,还是直接将过滤器应用于模型列。我从未在 models.py 文件中遇到过其中任何一个的示例(到目前为止我看到的所有过滤都在视图中)。我可以在 admin.py 文件的视图级别进行过滤,但这对基础表没有任何限制。
    • 嘿,是的,我是说,首先,您在模型中创建两个外键。您从查询本身执行过滤器,而无需读取 Diseasesyndromelink.objects.filter(disease__feildname="search") 的视图逻辑。如果它是Diseasesyndromelink 中的外键,请查看它们允许您访问和过滤疾病表字段的那些'__'。我理解正确吗?如果是,那么我会更新我的答案。
    • 嗨,我仍然不太确定我们是否在同一页面上。我需要确保不能在 DiseaseSyndromeLink.syndrome 字段中输入具有 disorder_type="disease" 的疾病。您是否建议而不是:class DiseaseSyndromeLink(models.Model): disease = models.ForeignKey('Disorder', models.DO_NOTHING, db_column='disease', related_name='disease') 我有类似的东西:class DiseaseSyndromeLink(models.模型): disease = Disorder.objects.filter(Disorder__disorder_type="Disease") 我无法将上述语法与将字段定义为 ForeignKey
    • 很抱歉给您带来了困惑。就您所说的“不能在 DiseaseSyndromeLink.syndrome 字段中输入具有disorder_type =“disease”的疾病而言,您必须在应用程序逻辑或模型自定义方法中实现它。我告诉你的是 ORM 中的读取查询。如果有混淆,请您更新问题,了解您的期望和您想要什么,您在问题中讨论了很多事情
    • 感谢您的宝贵时间。抱歉,原来的问题很难回答——它太复杂了,措辞也不好。我根据您的回答重新构建了问题。我认为最好在 MySQL 端强制执行约束。我认为在 Django 中编辑表单比对我认为您对 models.py 提出的更改进行更改相对容易,而我根本无法遵循。我只在 Django 视图中见过像你这样的代码,不知道从哪里开始在其他地方应用它!很抱歉给您带来不便。
    猜你喜欢
    • 1970-01-01
    • 2015-12-09
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多