按外键排列的唯一列,但似乎与另一个表的用途重复.这是一种愚蠢的做法吗



给定以下模型,其中我们有一个包含多个类别的菜单

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是唯一的,即菜单中没有重复的类别

  1. categories中包含menu_id和FK并添加如下所示的唯一约束是否简单
  2. 这不是重复了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)
);

相关内容

最新更新