给定以下模型,其中我们有一个包含多个类别的菜单
Menu *-- Categories
Menu A
- Category 1
- Category 2
- Category 3
Menu B
- Category blah
- Category 1
- Category 2
在数据库中
CREATE TABLE menus (
id UUID NOT NULL DEFAULT uuid_generate_v4() UNIQUE
);
CREATE TABLE categories (
id BIGSERIAL NOT NULL PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
CREATE TABLE menu_category_members (
menu_id UUID NOT NULL REFERENCES menus(id),
category_id BIGINT NOT NULL REFERENCES categories(id),
UNIQUE(menu_id, category_id)
);
// Menu
| id | name |
| 1 | Menu A |
| 2 | Menu B |
// Category
| id | name |
| 1 | Category 1 |
| 2 | Category 2 |
| 3 | Category 3 |
| 4 | Category blah |
| 5 | Category 1 |
| 6 | Category 2 |
// Category members
| menu_id | category_id |
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 4 |
| 2 | 5 |
| 2 | 6 |
我想确保每个菜单的categories.name
是唯一的,即菜单中没有重复的类别
- 在
categories
中包含menu_id
和FK并添加如下所示的唯一约束是否简单 - 这不是重复了
menu_category_members
表使表变得多余的目的吗
CREATE TABLE categories (
id BIGSERIAL NOT NULL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
menu_id UUID NOT NULL REFERENCES menus(id),
UNIQUE(name, menu_id)
);
在这种情况下,您应该简化结构,这是动态Menu实现中的最佳实践。
请参阅以下结构
// Menu
| id | name |
| 1 | Menu A |
| 2 | Menu B |
// Category
| id | name |parent_menu_id
| 1 | Category 1 |1
| 2 | Category 2 |1
| 3 | Category 3 |1
| 4 | Category blah |2
| 5 | Category 1 |2
| 6 | Category 2 |2
然后,您可以在parent_enu_id和name上实现Unique密钥约束,如下所示
CREATE TABLE categories (
id BIGSERIAL NOT NULL PRIMARY KEY,
name VARCHAR(100) NOT NULL
parent_menu_id BIGSERIAL NOT NULL,
CONSTRAINT uc_category UNIQUE (parent_menu_id,name)
);