sql - 转换为范式
问题描述
有区域、化身和区域实例。Avatar 必须属于每个区域的零个或一个实例。
CREATE TABLE zones (
id SERIAL NOT NULL PRIMARY KEY,
name VARCHAR NOT NULL,
...
);
CREATE TABLE avatars (
id SERIAL NOT NULL PRIMARY KEY,
...
);
CREATE TABLE instances (
id SERIAL NOT NULL PRIMARY KEY,
zone_id INTEGER REFERENCES zones NOT NULL,
...
);
CREATE TABLE avatar_instances (
avatar_id INTEGER REFERENCES avatars NOT NULL,
zone_id INTEGER REFERENCES zones NOT NULL,
instance_id INTEGER REFERENCES instances NOT NULL,
PRIMARY KEY(avatar_id, zone_id)
);
我对上面的模式不满意,因为zone_id
在每条记录中avatar_instances
都必须与zone_id
相应instances
行的内部一致。
理想情况下,我希望 avatar_instances 上的唯一索引“到达”instances
表的内部以查看instances.zone_id
.
例如
CREATE TABLE avatar_instances (
avatar_id INTEGER REFERENCES avatars NOT NULL,
instance_id INTEGER REFERENCES instances NOT NULL,
PRIMARY KEY(avatar_id, instance.zone_id)
);
如何将此模式转换为第 N 范式,同时保留“每个化身必须属于每个区域的零个或一个实例”的限制?
解决方案
创建一个唯一并添加一个引用唯一的复合 FK。
CREATE TABLE instances (
id SERIAL NOT NULL PRIMARY KEY,
zone_id INTEGER REFERENCES zones NOT NULL,
UNIQUE (zone_id, id)
);
CREATE TABLE avatar_instances (
avatar_id INTEGER REFERENCES avatars NOT NULL,
zone_id INTEGER NOT NULL,
instance_id INTEGER NOT NULL,
CONSTRAINT fk_ai2i FOREIGN KEY (zone_id, instance_id) REFERENCES instances (zone_id, id),
PRIMARY KEY(avatar_id, zone_id)
);
avatar_instances.instance_id
如果 Avatar 必须属于每个区域的零个或一个实例,则允许输入 null 。
推荐阅读
- php - composer 需要 symfony/assets 安装
- asp.net - 无法在 MySql DbContext 的 dotnet ef 迁移中创建对象错误,但适用于 Sqlite DbContext
- javascript - 如何使用 JavaScript 在标准 HTML 文本中显示插入符号?
- c# - 解决方案 repo 结构 -VS Azure 函数
- android - MissingPluginException(未找到通道 video_thumbnail 上的方法文件的实现)
- wpf - 如何以编程方式将多个字符串添加到多列 ListView 中的一行
- visual-studio-code - 在 VS Code(css 文件)中更改 jupyter 笔记本样式
- python - 我怎样才能在我的机器人状态中制作公会计数器。不和谐.py
- sql - 使用动态列名在 SQL 中展平表
- android-studio - Android Studio 模拟器扩展控件位置屏幕未加载