我在json中存储了以下格式来存储律师,我怀疑如何在postgres中建模“特色”字段,其中包含一个对象数组,每个对象都有一个标题和子专业的子数组:
{
"id": 1,
"name": "John Johnson Johannes",
"gender": "f",
"specialties": [
{
"specialty": "Business law",
"sub-specialties": [
"Incorporation",
"Taxes",
"Fusions"
]
},
{
"specialty": "Criminal law",
"sub-specialties": [
"Property offenses",
"Personal offenses",
"Strict liability"
]
}
]
}
我在Postgres做了这个律师表:
DROP DATABASE IF EXISTS lawyers_db;
CREATE DATABASE lawyers_db;
\c lawyers_db;
CREATE TYPE gen AS ENUM ('f', 'm');
CREATE TABLE lawyers_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR,
gender gen
);
INSERT INTO lawyers_tb (name, gender)
VALUES ('John Doe', 'm');
我正在使用一些node.js库,当我从Postgres表读取数据时,它将数据作为JSON返回,因此我想保留关系模型,而不使用JSONb作为文档存储我的律师。
是否有可能在不使用JSONb类型的情况下实现我想要的目标?
答案 0 :(得分:0)
暂时忘掉对象并真正思考数据是什么以及它们之间的关系(我们毕竟使用关系数据库)。
你在这里只是一种关系。
你有律师,你有专业。这种关系是律师拥有专业和专业属于律师(n-to-n关系),专业与专业(n-to-n)之间的关系也是如此。
首先,让我们做一个简单的1对n关系结构:
id
这有效,但会产生重复,因为每个专业只能属于一名律师,因此,如果两位律师专注于“商业法”和#34;你必须定义"商业法"两次。更糟糕的是,对于每个专业,您还必须复制子专业。
解决方案是连接表(也称为映射/映射表):
CREATE TABLE lawyers_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR,
gender gen
);
CREATE TABLE specialties_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR,
lawyer_ID INTEGER
);
CREATE TABLE subspecialties_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR,
specialty_ID INTEGER
);
这样每个专业都可以属于不止一个律师(真正的n对n关系),每个专业都可以属于不止一个专业。
您可以使用联接来获取整个数据集:
CREATE TABLE lawyers_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR,
gender gen
);
CREATE TABLE lawyer_specialties_tb (
name VARCHAR,
lawyer_ID INTEGER,
specialty_ID INTEGER
);
CREATE TABLE specialties_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR
);
CREATE TABLE specialty_subspecialties_tb (
name VARCHAR,
specialty_ID INTEGER,
subspecialty_ID INTEGER
);
CREATE TABLE subspecialties_tb (
ID SERIAL PRIMARY KEY,
name VARCHAR
);
是的,查询起来有点复杂,但结构允许您单独维护每个数据集并定义它们之间的正确关系。
您可能还希望将连接表中的键定义为外键,以强制执行数据集的正确性。