多个复选框的数据模型

Data Model for multiple checkboxes

我目前有一个 供应商 table,现在我想存储每个供应商服务的区域。

<form method="post" action="/Tests/Post/">      
    <fieldset>      
        <legend>What is Your Served Region ?</legend>      
        <input type="checkbox" name="served_region" value="Europe">Europe<br>      
        <input type="checkbox" name="served_region" value="Asia">Asia<br>      
        <input type="checkbox" name="served_region" value="Africa">Africa<br>      
        <br>      
        <input type="submit" value="Submit now" />      
    </fieldset>      
</form>

作为第一个想法,我制作了这样的供应商模型:

CREATE TABLE supliers (
  supplier_id SERIAL PRIMARY KEY NOT NULL,
  name VARCHAR(255),
  email VARCHAR(255) UNIQUE NOT NULL,
  servesAfrica BOOLEAN NOT NULL DEFAULT false,
  servesEurope BOOLEAN NOT NULL DEFAULT false,
  servesAsia BOOLEAN NOT NULL DEFAULT false
);

这看起来是个不错的模式吗?特别是对于按服务地区过滤供应商的查询等。 如果以后我想增加更多的区域,这个方案还可靠吗?

我认为您需要像下面这样更规范化的东西。 这样,您还可以在不更改表架构的情况下添加新区域。 在您的示例中,您需要在新区域的情况下添加新列。 在下面你只需要添加新行。

CREATE TABLE regions (
  id SERIAL PRIMARY KEY NOT NULL,
  name VARCHAR(255) NOT NULL
);

CREATE TABLE suppliers (
  supplier_id SERIAL PRIMARY KEY NOT NULL,
  name VARCHAR(255),
  email VARCHAR(255) UNIQUE NOT NULL,
  region_id INT NOT NULL,
  CONSTRAINT fk_regions
    FOREIGN KEY (region_id)
    REFERENCES regions(id)
);

如果您正在寻找一个更“分析”的层,即不是那么规范化,以下也可以工作,只是您会大量复制“region_name”。

CREATE TABLE suppliers (
  supplier_id SERIAL PRIMARY KEY NOT NULL,
  name VARCHAR(255),
  email VARCHAR(255) UNIQUE NOT NULL,
  region_name VARCHAR(255)
);

同意 romborimba,但如果我没听错,您可以将多个区域分配给一个供应商。在这种情况下,我会使用绑定 table

QuickSQL

Binding_tbl
  ID
  Supplier_ID
    ID
    NAME
    EMAIL
  REGION_ID
    ID
    NAME

Is this solution still reliable if in the future I want to add more regions?

没有。添加另一个区域需要:

  • 正在向数据库添加新列table
  • 修改您的应用程序代码以引用该新列

在实时应用程序中更改数据模型和应用程序代码始终是一个痛点。 (具体有多痛苦取决于你的改变过程。)

更好的设计是具有 table 个区域和 table 个 SUPPLIER_REGIONS 的交集。围绕该结构构建您的应用程序并添加新区域仅仅是一些插入语句的问题。

CREATE TABLE suppliers (
  supplier_id SERIAL PRIMARY KEY NOT NULL,
  name VARCHAR(255),
  email VARCHAR(255) UNIQUE NOT NULL
);
CREATE TABLE regions (
  region_id SERIAL PRIMARY KEY NOT NULL,
  region_name VARCHAR(255)
);
CREATE TABLE supplier_regions (
  supplier_id SERIAL NOT NULL,
  region_id SERIAL PRIMARY KEY NOT NULL,
  constraint supplier_regions_pk primary key (supplier_id, region_id),
  constraint supplier_regions_supplier_fk foreign key (supplier_id) references suppliers (supplier_id),
  constraint supplier_regions_region_fk foreign key (region_id) references regions (region_id)
);

Is it optimal to create an additional table for just 3 values: Europe, Africa and Asia?

仁者见仁智者见智。

考虑另一个变化:让我们将 CUSTOMERS 添加到组合中。我们想知道我们的客户属于哪个地区。我们还添加了 WAREHOUSES,并想知道它们位于哪个区域。现在我们想知道:哪个仓库最适合存储供应商 X 的产品?哪个仓库最适合向客户 Y 交货?使用单个 REGIONS table 连接多个依赖 tables 比连接实体 tables.

上的标志列更容易回答此类问题

your proposed solution will make it possible to do operations on the region table like adding more fields (translate name etc)

这是一个很好的见解。数据建模的目的之一是驱逐领域中的所有核心实体。我们要为其存储多个属性的事物需要独立 tables.