“延长”关系数据库中的关系

发布于 2024-10-24 20:54:59 字数 1050 浏览 3 评论 0原文

你好,
我目前正在尝试应用最有效的方法来存储关系数据库中实体之间的“扩展”关系。

举例来说,假设我们有以下简化实体:

  • User
  • Student (扩展 User
  • Teacher (扩展 User

User 包含适用于 StudentTeacher 的属性。 StudentTeacher 都包含它们独有的自定义属性。

首先想到的是创建一个表,其中包含所有单一数据的列(即除了一对多字段):

User
-------------
User ID
First name
Last name
Student class
Teacher office no.
Teacher description
...

然而,从存储的角度来看,这不会非常有效,因为:

  • 大多数行将包含学生,教师数量较少,
  • 教师将拥有更多独特的列,这会浪费学生行的空间


复制实体之间的关系会更有效:

User
-------------
User ID
First name
Last name
...


Student
-------------
User ID
Student class
...


Teacher
-------------
User ID
Teacher office no.
Teacher description
...

所以我的问题是:

  1. 上述问题是否太过分了,即我们是否应该将存储效率留给数据库引擎?
  2. 就标准化而言,将实体拆分为 3 个表仍然可以吗?
  3. 如果这不是一个好方法,您建议如何处理关系数据库中的“扩展”关系?

谢谢。

Hello,
I'm currently trying to apply the most efficient way to store an "extend" relationship between entities in a relational database.

For the sake of example, lets say we have the following simplified entities:

  • User
  • Student (extends User)
  • Teacher (extends User)

User contains attributes which apply to both Student and Teacher. Both Student and Teacher contain custom attributes which are unique to them.

The first thing that comes to mind is to create a single table with columns for all singular data (i.e. except one-to-many fields):

User
-------------
User ID
First name
Last name
Student class
Teacher office no.
Teacher description
...

This however won't be very efficient from a storage perspective, because:

  • the majority of rows will contain students, with a small number of teachers
  • teachers will have much more unique columns, which would waste space in students' rows

It would be more efficient to replicate relationships between the entities:

User
-------------
User ID
First name
Last name
...


Student
-------------
User ID
Student class
...


Teacher
-------------
User ID
Teacher office no.
Teacher description
...

So my questions are:

  1. Is the above concern taking it too far, i.e. should we leave storage efficiency to the database engine?
  2. Is splitting the entities into 3 tables still OK in terms of normalization?
  3. If it's not a good approach, how would you recommend to treat "extend" relationships in a relational database?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我做我的改变 2024-10-31 20:54:59

如果用户不能既是教师又是学生,那么您将面临一个简单的超类型/子类型问题。 (我在关系数据库设计意义上使用超类型子类型,而不是在面向对象编程意义上。)您只存储在“学生”中是正确的那些描述学生的属性,并仅将那些描述教师的属性存储在“教师”中。

-- Supertype: users
create table users (
  user_id integer not null unique,
  user_type char(1) not null 
    check (user_type in ('T', 'S')),
  -- other user columns
  primary key (user_id, user_type)
);

-- Subtype: students
create table students_st (
  user_id integer not null,
  user_type char(1) not null default 'S'
    check (user_type = 'S'),
  locker_num integer not null unique 
    check (locker_num > 0),
  -- other student columns
  primary key (user_id, user_type),
  foreign key (user_id, user_type) 
    references users (user_id, user_type) 
    on delete cascade
);

-- Subtype: teachers
create table teachers_st (
  user_id integer not null,
  user_type char(1) not null default 'T'
    check (user_type = 'T'),
  office_num char(4),
  -- other teacher columns
  primary key (user_id, user_type),
  foreign key (user_id, user_type) 
    references users (user_id, user_type) 
    on delete cascade
);

create view teachers as 
select u.user_id,
       u.user_type,
       -- other user columns
       t.office_num
       -- other teacher columns
from users u
inner join teachers_st t on (u.user_id = t.user_id);

create view students as 
select u.user_id,
       u.user_type,
       -- other user columns
       s.locker_num
       -- other student columns
from users u
inner join students_st s on (u.user_id = s.user_id);

此时,您还需要执行 dbms 所需的任何操作来使这两个视图可更新 — 触发器、规则等。应用程序代码从视图而不是基表中插入、更新和删除。

If a user can't be both a teacher and a student, then you're looking at a straightforward supertype/subtype problem. (I'm using supertype and subtype in their relational database design sense, not in their object-oriented programming sense.) You're right to store in "students" only those attributes that describe students, and to store in "teachers" only those attributes that describe teachers.

-- Supertype: users
create table users (
  user_id integer not null unique,
  user_type char(1) not null 
    check (user_type in ('T', 'S')),
  -- other user columns
  primary key (user_id, user_type)
);

-- Subtype: students
create table students_st (
  user_id integer not null,
  user_type char(1) not null default 'S'
    check (user_type = 'S'),
  locker_num integer not null unique 
    check (locker_num > 0),
  -- other student columns
  primary key (user_id, user_type),
  foreign key (user_id, user_type) 
    references users (user_id, user_type) 
    on delete cascade
);

-- Subtype: teachers
create table teachers_st (
  user_id integer not null,
  user_type char(1) not null default 'T'
    check (user_type = 'T'),
  office_num char(4),
  -- other teacher columns
  primary key (user_id, user_type),
  foreign key (user_id, user_type) 
    references users (user_id, user_type) 
    on delete cascade
);

create view teachers as 
select u.user_id,
       u.user_type,
       -- other user columns
       t.office_num
       -- other teacher columns
from users u
inner join teachers_st t on (u.user_id = t.user_id);

create view students as 
select u.user_id,
       u.user_type,
       -- other user columns
       s.locker_num
       -- other student columns
from users u
inner join students_st s on (u.user_id = s.user_id);

At this point, you'd also do whatever your dbms requires to make these two views updatable—triggers, rules, whatever. Application code inserts, updates, and deletes from the views, not from the base tables.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文