Sql 数据库设计:如何存储列属性?

Sql 数据库设计:如何存储列属性?,sql,postgresql,database-design,Sql,Postgresql,Database Design,我有一个web应用程序,它有许多表单和许多字段。这些字段中有些是必需的,有些不是,但我希望能够将表单值保存在数据库表中,以便用户可以保存他们的进度。如何存储有关列的元信息?具体来说,假设我有一张桌子: create table form1 ( field1 text, field2 text, -- ... fieldn text ) 我想存储某个地方需要哪些字段的业务逻辑,这样我就可以查询数据库以获得如下信息: ('field1_val', true, nu

我有一个web应用程序,它有许多表单和许多字段。这些字段中有些是必需的,有些不是,但我希望能够将表单值保存在数据库表中,以便用户可以保存他们的进度。如何存储有关列的元信息?具体来说,假设我有一张桌子:

create table form1 (
    field1 text, 
    field2 text,
    -- ...
    fieldn text
)
我想存储某个地方需要哪些字段的业务逻辑,这样我就可以查询数据库以获得如下信息:

('field1_val', true, null, false, ..., 'fieldn_val', true)
{
  "field_1": {"name": "Lastname", "required": true }}, 
  "field_2": {"name": "Firstname", "required": false }}
}
其中,每个奇数列是存储在表中的值,偶数列是字段是否为必填项。我考虑使用一个单独的表来存储需求数据,如下所示:

create table form1_requirements (
    table_name text, 
    field_name text,
    required boolean
);
insert into form1_requirements values ('foo', 'field1', true);
insert into form1_requirements values ('foo', 'field2', false);
insert into form1_requirements values ('foo', 'fieldn', true);
然而,我不确定是否有可能进行这样的连接,以及这样做是否明智


这方面的最佳解决方案是什么?我主要对postgresql感兴趣,但也对mysql和sqlite3感兴趣。

为什么不将您需要的列定义为
NOTNULL

create table form1 (
    field1 text not null, 
    field2 text,
    -- ...
    fieldn text not null
);

然后需要声明为
notnull
的字段。

我将not这样存储这些字段。字段应位于单独的表中,与表单表具有一对多关系:

create table form
(
   id integer primary key,
   name text not null unique, 
   ... other columns for the form ...
);

create table field
(
  id integer primary key, 
  form_id integer not null reference form
  name text not null, 
  required boolean,
  ... other columns describing a single field, e.g. the data type ...
);
单个值应存储在单独的表中:

create table form_values
(
  form_id integer not null references form,
  field_id integer not null references field,
  value text,
  primary key (form_id, field_id)
);
以上也被称为“实体属性值”设计模式

另一个选项是将该信息存储在
json
列中:

create table form
(
   id integer primary key,
   name text not null unique, 
   field_definitions jsonb
);
在列字段_definitions中,存储如下内容:

('field1_val', true, null, false, ..., 'fieldn_val', true)
{
  "field_1": {"name": "Lastname", "required": true }}, 
  "field_2": {"name": "Firstname", "required": false }}
}

您仍然应该使用第二个表来存储实际字段值。您还可以将单个表单的所有值存储在一个JSON列中。

我希望能够存储不完整的表单,正如我在问题中所说的。因此,使用Gordon的想法,当第一次插入失败时,将不完整的表单数据存储在一个单独的表中,但是使用dB字典中的元数据来定义NOTNULL约束。甚至可以在这里保留注释和默认值,这当然可以解决我遇到的问题。。。。但我忍不住想,这会让数据的使用成为一件麻烦事,因为如果我想对所有表单值进行简单的选择,我必须对每列进行自连接,对吗?@user3243135:是的,这是这种通用数据模型的缺点之一。将其存储在单个JSON列中会使这一部分更容易