如何模拟 (a) 物业与业主之间以及 (b) 物业与租户之间的关系?

Req*_*que 6 mysql schema database-design

我有一个数据库设计,但在处理两个表时遇到了问题。我有一个用户表和一个属性表。该属性表可仅具有0,1,或2个用户,让我们称他们的所有者和租户,并且仅在每个中的一个(每属性),和一个用户可以是雇主或在许多房客属性

因此,根据案例,这是我的两个选择:

  1. Properties表中有两个外键(因为一个属性引用的最大用户数是 2 而不是 N),称为 owner_id 和tenant_id,它们引用了Users表。
  2. 有一个 N:M 中间表,包含 user_id 和 property_id,以及指示该属性中用户类型的另一列(比如布尔值 1 = 所有者,0 = 租户)。

哪个是最好的设计选择?

说明

  • 一个用户有一个姓名和电子邮件,以及财产一条街以及其作为属性数。
  • 一个用户可能只是在业主或租客财产,而不是两个,因为所有者意味着他拥有的财产(阉,他住在这里与否),与租客是另一个用户实际上生活在那里的,所以需要有一个老板在添加租户之前。
  • 一个属性可能没有用户分配。

MDC*_*CCL 4

商业规则

\n\n

因此,(1) 在我们通过评论和聊天进行了一些审议之后,(2) 一旦您与客户和同事讨论了可能性,事实上就已经定义:

\n\n
    \n
  • 一个Property有零个或多个Owner,每个 Owner 必须是一个User
  • \n
  • 用户是零个或多个属性所有者
  • \n
  • 一个属性有零个或多个租户,每个租户都必须是用户
  • \n
  • 用户是零个或多个属性租户
  • \n
  • 房产通过其街道号码组合来唯一标识
  • \n
  • 用户由其电子邮件地址唯一标识
  • \n
\n\n

因此 \xe2\x80\x94 在您的业务上下文 \xe2\x80\x94 等方面,实体类型Property和之间存在两种不同的基数多对多 (M:N) 概念级关联(或关系)用户.

\n\n

IDEF1X 说明图

\n\n

因此,我创建了一个 IDEF1X 1图表,整合了上面制定的业务规则,如图 1 所示:

\n\n

图 1 - IDEF1X 财产所有权和租赁图

\n\n

如所示,每个实体类型 \xe2\x80\x94 是关联的还是独立的\xe2\x80\x94)都通过其单独的框来描绘。

\n\n

我将 (a)ownership和 (b)描述为两种不同的关联实体类型,因为虽然非常相似,但它们代表了两个不同的感兴趣事物tenancy的原型,因此单独管理它们非常方便,因为,例如:

\n\n
    \n
  • 除了\n\n
      \n
    1. 仅仅保留一个事实,即给定user是通过true 或 false属性 \xe2\x80\x94named的tenant方式,例如,和ownerpropertyis_owneris_tenant\xe2\x80\x94
    2. \n
  • \n
  • 你可能也有兴趣

    \n\n
      \n
    1. 保持所有和实例在系统中注册时的确切时间点,从而建立一个与时间相关的属性 \xe2\x80\x94entitled,例如,ownershiptenancycreated_datetime,从而为所述实体类型建立一个名为 \xe2\x80\x94 的时间相关属性,例如 \xe2\x80\x94 将是非常有利的。
    2. \n
  • \n
  • 将来,这些实体类型中的一种可能需要跟踪不适用于另一种的某些属性,因此离散地管理它们从一开始就会产生好处,从而形成更具可扩展性和通用性的概念模式。

  • \n
\n\n

值得一提的是,在图中,user_id属性从 (i)user实体类型迁移到 (ii)和ownership(ii)tenancy分别为\xe2\x80\x94 ,这两个角色名称都是您在问题中提供的具有相当描述性的角色名称\xe2 \x80\x94。owner_idtenant_id

\n\n

说明性逻辑 SQL-DDL 设计

\n\n

然后,根据上面详述的 IDEF1X 图,我编写了说明性 DDL 布局,声明如下:

\n\n
-- You should determine which are the most fitting \n-- data types and sizes for all your table columns \n-- depending on your business context characteristics.\n\n-- Also, you should make accurate tests to define the \n-- most convenient INDEX strategies based on the exact \n-- data manipulation tendencies of your business domain.\n\n-- As one would expect, you are free to utilize \n-- your preferred (or required) naming conventions. \n\nCREATE TABLE user_profile (\n    user_id          INT      NOT NULL,\n    first_name       CHAR(30) NOT NULL,\n    last_name        CHAR(30) NOT NULL,\n    gender_code      CHAR(3)  NOT NULL,\n    birth_date       DATE     NOT NULL,\n    email_address    CHAR(30) NOT NULL,\n    created_datetime DATETIME NOT NULL,\n    --\n    CONSTRAINT user_profile_PK  PRIMARY KEY (user_id),\n    CONSTRAINT user_profile_AK1 UNIQUE ( -- Multi-column ALTERNATE KEY.\n        first_name,\n        last_name,\n        gender_code,\n        birth_date\n    ),\n    CONSTRAINT user_profile_AK2 UNIQUE (email_address) -- Single-column ALTERNATE KEY.\n);\n\nCREATE TABLE property (\n    property_id      INT      NOT NULL, \n    street           CHAR(30) NOT NULL,\n    number           CHAR(30) NOT NULL,\n    created_datetime DATETIME NOT NULL,\n    -- \n    CONSTRAINT property_PK PRIMARY KEY (property_id),\n    CONSTRAINT property_AK UNIQUE      (street, number) \n);\n\nCREATE TABLE ownership (\n    property_id      INT      NOT NULL, \n    owner_id         INT      NOT NULL,   \n    created_datetime DATETIME NOT NULL,\n    --\n    CONSTRAINT property_PK              PRIMARY KEY (property_id, owner_id),\n    CONSTRAINT ownership_to_property_FK FOREIGN KEY (property_id)\n        REFERENCES property (property_id),\n    CONSTRAINT ownership_to_owner_FK    FOREIGN KEY (owner_id)\n        REFERENCES user_profile (user_id)\n);\n\nCREATE TABLE tenancy (\n    property_id      INT      NOT NULL, \n    tenant_id        INT      NOT NULL,   \n    created_datetime DATETIME NOT NULL,\n    --\n    CONSTRAINT tenancy_PK             PRIMARY KEY (property_id, tenant_id),\n    CONSTRAINT tenancy_to_property_FK FOREIGN KEY (property_id)\n        REFERENCES property (property_id),\n    CONSTRAINT tenancy_to_tenant_FK   FOREIGN KEY (tenant_id)\n        REFERENCES user_profile (user_id)\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,在这样的逻辑层次设计中:

\n\n
    \n
  • 每个基表代表一个单独的实体类型(这可以防止由于同一基表表示不同的含义和意图而引起的歧义);
  • \n
  • 代表相应实体类型的特定属性;
  • \n
  • 每列都有固定的特定数据类型,以确保它包含的所有都属于单个且定义良好的集合,无论是 INT、DATETIME、CHAR 等;和
  • \n
  • (以声明方式)配置多个约束,以保证所有表中保留的形式的断言符合概念模式中确定的业务规则。
  • \n
\n\n

所有这些都符合Edgar Frank Codd 博士在其关系模型中的规定(在撰写本文时结构化查询语言的功能允许的范围内)。

\n\n

当然,使用这种逻辑布局,您仍然可以借助SELECT 操作(生成计算结果为“True”的标量值)以布尔形式导出给定用户是否是特定属性的所有者。 \' 或 \'False\',可以从共享此数据库的一个或多个(当前或将来)应用程序访问。

\n\n

用相同的逻辑层次安排覆盖初始业务规则

\n\n

这些方面现在大多是轶事,但一些最初的业务规则是:

\n\n
    \n
  • 属性有零个或一个Owner 它必须是User
  • \n
  • 用户是零个或多个属性所有者
  • \n
  • 一个Property有零个或一个Tenant,它必须是User
  • \n
  • 用户是零个或多个属性租户
  • \n
\n\n

并且可以使用前面讨论的相同逻辑设计来处理它们,通过另外两个约束将列声明为和表property_id中的 ALTERNATE KEY ,即:ownershiptenancy

\n\n
ALTER TABLE ownership\n    ADD CONSTRAINT UNIQUE ownership_AK (property_id);\n\nALTER TABLE tenancy\n    ADD CONSTRAINT UNIQUE tenancy_AK (property_id);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这显示了该答案中提出的安排所提供的多功能性的其他方面(这可以对未来的访问者有所帮助)。

\n\n
\n\n

尾注

\n\n

1 信息建模集成定义( IDEF1X ) 是一种高度推荐的数据建模技术,由美国国家标准与技术研究所(NIST) 于 1993 年 12 月制定为标准。它完全基于 (a) 关系模型创始人 EF Codd 博士撰写的一些理论著作;(b)实体关系观,由PP Chen 博士提出;以及 (c) 逻辑数据库设计技术,由 Robert G. Brown 创建。

\n