mysql - 将表格的行关联到组中,每个组中都有特殊元素
问题描述
我有一张桌子items (id, varchar name)
。我想创建一种将item
s 分组的方法。每个都item
应该在一个中group
。每个组应该至少有一个item
,可能有多个。每个都group
应该有一个item
被指定为特殊的 s ,并且那item
必须是 that 的成员group
。应该可以选择 anyitem
作为 selected item
,并且应该可以更改 a 中的哪item
一个group
是选中的。
我正在使用最新版本的 MySQL,该items
表使用 InnoDB。
如何将这些约束编码到 SQL 设计中?我知道如何创建一个 n 对 1 关联表,但我不知道如何编码“恰好一个特殊元素”部分。
我目前的尝试使用一张桌子group (id)
和
group_item (
id,
group_id,
item_id,
unique key item_id,
selected enum("selected") null,
unique key (group_id, selected)
)
但这并不能确保至少选择了一个元素,而且我不确定该设计是否朝着正确的方向发展。
不幸的是,我似乎找不到一个好的术语来搜索试图实现这种设计的文献或代码——我花了相当多的时间搜索谷歌和 Stack Overflow 以及一些 SQL 书籍.
解决方案
这是一个可能的解决方案,但是,它不满足所有约束。
创建一个组表,让我们
id
为其标识符。将组的外键添加到项目表中,
group_id
. 这满足了“每个项目都应该在一个组中”的约束。组表应该有一个属性
selected_item
,项目表的外键。这满足了“每个组应该有一个被指定为特殊的项目”的约束。
此解决方案不满足的约束是:
每个组应该至少有一个项目。
每个组都应该有一个被指定为特殊的项目,并且该项目必须是该组的成员。
应用程序可以通过两个简单的查询来强制执行这两个约束:第一个约束可以通过检查或删除没有任何项目的组的查询来强制执行,例如:
DELETE FROM groups g
WHERE NOT EXISTS (SELECT * FROM items i WHERE i.group_id = g.id)
第二个带有查询,检查selected_item
每个组中的 是否引用了具有该组的某些项目group_id
。就像是:
SELECT *
FROM groups g
WHERE selected_item NOT IN (SELECT item_id FROM items i WHERE i.group_id = g.id)
AND selected_item IS NOT NULL
(如果属性可以为空,则可能带有附加条件)。
或者,您可以添加触发器以自动执行约束。
推荐阅读
- node.js - TypeError:无法读取汇总包 [monorepo] [yarn 工作区] [nodejs] 中未定义的属性“组合”
- css - MaterialIcon 中的主题(例如轮廓、填充等)不起作用
- flutter - 底部溢出 230 像素的 RenderFlex
- javascript - 对于 Angular 8 - 无法通过 NgModuleFactoryLoader.load(path: string) 加载类型函数的Children
- php - 我如何访问这个 php 数组字符串值
- python - 如何读写这个文件?
- unit-testing - 没有与 --testNamePattern CLI 选项匹配的测试时失败
- java - 我需要有人为我解释这个 java 代码
- sql-server - SQLAlchemy 原始 sql 与 where 子句中的列表 mssql pyodbc
- sql-server - 使用更改文件名自动将 csv 文件上传到 SQL Server