在下图中,您可以看到我有用户个人资料。用户意味着配置文件与登录名相关联。如果他们没有登录帐户,那么它们只是您在右侧看到的公司表上的“联系人”。
我正在创建一个CRM,该CRM需要能够存储许多设施,客户,供应商等。
我的问题是,我该如何将该个人资料与其所属的公司相关联?例如,如果我转到那里的个人资料页面,则无论该公司位于哪个表中,我都应该查看他们工作的公司。
我有2个想法,但似乎都存在缺陷。一种是为每个联系人创建一个单独的配置文件表。例。 vendor_profiles
,customer_profiles
等。这看起来很混乱。
我的另一个想法是在配置文件表中创建一个vendor_id
,customer_id
等列,默认将它们全部设置为NULL
,如果它们属于供应商,那么我应用程序代码会检查每个数字,我想您从那里知道我要去的地方。再次,看起来很凌乱,效率低下。
我还考虑过将供应商,客户等分组到一个表中,并只是设置一个“类型”,但是它们都存储了非常不同的信息,并且以不同的,经常是关系的方式使用。
答案 0 :(得分:1)
引入一个新的organization
表,该表统一了vendor
,customer
,
它们都共享的facility
和our_company
:
CREATE TABLE organization (
organization_id serial4
type text);
CREATE TABLE profile (
profile_id serial4
user_id int4 REFERENCES user
organization_id int4 REFERENCES organization
...);
然后将organization_id
外键添加到vendor
,customer
,facility
和our_company
因此,当需要这些表中的额外信息时,可以将这些表连接到organization
。
CREATE TABLE vendor (
vendor_id serial4
organization_id int4 REFERENCES organization
vendor_specific_field text
...);
请注意,如果您对ID字段使用“唯一”名称(例如organization_id
而不是id
),而这些名称在所有表中的含义都一致,那么您可以使用JOIN ... USING
语法< / p>
SELECT *
FROM profile p
INNER JOIN organization o USING (organization_id)
INNER JOIN vendor v USING (organization_id)
WHERE o.type = 'vendor'
代替
SELECT *
FROM profile p
INNER JOIN organization o ON p.organization_id = o.id
INNER JOIN vendor v ON v.organization_id = o.id
WHERE o.type = 'vendor'
这可以提高可读性并减少连接条件中的潜在错误。 (您不必怀疑一个表中的哪个字段连接到另一个表中的id
字段。)