Lược đồ cơ sở dữ liệu cho các thực thể với hai loại chủ sở hữu / cha mẹ có thể?


8

Tôi đang sử dụng PostgreSQL với Sequelize làm ORM của mình.

Tôi có một loại , User. Loại thứ hai là Group, có thể có bất kỳ số lượng người dùng nào được liên kết với nó thông qua một GroupMembershipsbảng. Users cũng có thể sở hữu bất kỳ số lượng Groups.

Loại thứ ba của tôi Playlist, có thể thuộc về UserHOẶC a group. Điều gì sẽ là cách tốt nhất để thiết kế một lược đồ cho loại này để nó có thể có một loại chủ sở hữu hoặc một trong hai?

Vượt qua đầu tiên của tôi, tôi đã tạo ra cả hai hiệp hội, nhưng mỗi lần chỉ có một hiệp hội. Điều này có thể có thể làm việc, nhưng có vẻ hacky và làm cho các truy vấn khó khăn.

Thông tin thêm

Dưới đây là những phản hồi của tôi đối với các yêu cầu làm rõ được đăng tải bởi MDCCL thông qua các bình luận:

(1) Nếu Danh sách phát được sở hữu bởi một Nhóm nhất định , người ta có thể nói rằng Danh sách phát này có liên quan đến nhiều người dùng , miễn là họ là Thành viên của Nhóm đó , phải không?

Tôi tin rằng điều này là đúng về mặt kỹ thuật, nhưng hiệp hội một-nhiều này không tồn tại rõ ràng.

(2) Vì vậy, một Danh sách phát cụ thể có thể được sở hữu bởi một-nhiều Nhóm cùng một lúc không?

Không, không thể Playlistsở hữu một-nhiều người Groups.

(3) Có thể một Danh sách phát cụ thể được sở hữu bởi một-nhiều Nhóm và đồng thời, bởi một hoặc nhiều Người dùng không phải là Thành viên của Nhóm đó không?

Không, vì như trong (2) một từ nhiều Playlistđến Groupkhông nên tồn tại. Ngoài ra, nếu a Playlistthuộc sở hữu của a Groupthì nó không thuộc sở hữu của a Uservà ngược lại. Chỉ có một chủ sở hữu tại một thời điểm.

(4) Các thuộc tính được sử dụng để xác định duy nhất Nhóm , Người dùngDanh sách phát là gì?

Mỗi cái đều có khóa chính thay thế ( id), cũng như khóa tự nhiên (mặc dù không phải là khóa chính). Đây là slugcho GroupPlaylist, và usernamecho User.

(5) Có thể một đặc biệt Danh sách phát bị một Chủ đầu tư thay đổi?

Mặc dù tôi không có kế hoạch cho việc đây là một tính năng (ít nhất là ban đầu), tôi cho rằng điều này có thể xảy ra theo giả thuyết.

(6) Ý nghĩa của các thuộc tính Group.SlugPlaylist.Slug là gì? Giá trị của chúng có đủ ổn định để được xác định là khóa chính hay chúng thay đổi rất thường xuyên? Các giá trị của hai thuộc tính này, cùng với User.Username phải là duy nhất, đúng không?

Đây sluglà những phiên bản duy nhất, chữ thường, gạch nối của thực thể tương ứng title. Ví dụ: a groupvới title'Nhóm thử nghiệm' sẽ có slug'nhóm thử nghiệm'. Các bản sao được nối với số nguyên tăng dần. Điều này sẽ thay đổi bất cứ lúc nào thay đổi của họ title. Tôi tin rằng điều đó có nghĩa là họ sẽ không tạo ra các khóa chính tuyệt vời? Có, slugsusernameslà duy nhất trong các bảng tương ứng của họ.

Câu trả lời:


9

Nếu tôi hiểu đúng các thông số kỹ thuật của bạn, kịch bản của bạn liên quan đến các khía cạnh quan trọng khác của Wapamong, một cấu trúc siêu kiểu phụ .

Tôi sẽ minh họa bên dưới cách (1) mô hình hóa nó ở mức độ trừu tượng khái niệm và sau đó (2) thể hiện nó trong một thiết kế DDL ở mức logic .

Quy tắc kinh doanh

Các công thức khái niệm sau đây là một trong những quy tắc quan trọng nhất trong bối cảnh kinh doanh của bạn:

  • Một danh sách nhạc thuộc sở hữu của một trong hai chính xác một Nhóm hoặc chính xác một tài khoản tại một điểm cụ thể trong thời gian
  • Một danh sách nhạc có thể được sở hữu bởi một-nhiều nhóm hoặc người sử dụng tại các điểm khác nhau trong thời gian
  • Một tài khoản sở hữu zero-một-hoặc-nhiều Playlists
  • Một nhóm sở hữu danh sách phát không có một hoặc nhiều
  • Một nhóm được tạo thành từ một đến nhiều Thành viên (phải là Người dùng )
  • Một tài khoản có thể là một thành viên của zero-một-hoặc-nhiều nhóm .
  • Một nhóm được tạo thành từ một đến nhiều Thành viên (phải là Người dùng )

Vì các liên kết hoặc mối quan hệ (a) giữa Người dùngDanh sách phát và (b) giữa NhómDanh sách phát khá giống nhau, nên thực tế này cho thấy Người dùngNhómcác kiểu con thực thể loại trừ lẫn nhau của Bên 1 , đến lượt họ là siêu thực thể của họ. cụm phụ là các cấu trúc dữ liệu cổ điển xuất hiện trong các lược đồ khái niệm về các loại rất đa dạng. Theo cách này, hai quy tắc mới có thể được khẳng định:

  • Một bên được phân loại theo chính xác một PartyType
  • Một bên là một nhóm hoặc một người dùng

Và bốn trong số các quy tắc trước đây phải được cải cách thành ba:

  • Một danh sách nhạc thuộc sở hữu của chính xác một Đảng tại một điểm cụ thể trong thời gian
  • Một danh sách nhạc có thể được sở hữu bởi một-nhiều Bên tại các điểm khác nhau trong thời gian
  • Một Bên sở hữu Danh sách phát không có một hoặc nhiều

Sơ đồ IDEF1X tiếp xúc

Sơ đồ IDEF1X 2 được hiển thị trong Hình 1 hợp nhất tất cả các quy tắc kinh doanh đã nói ở trên cùng với các quy tắc khác xuất hiện thích hợp:

Hình 1 - Sơ đồ sở hữu danh sách phát IDEF1X

Như đã trình bày, NhómNgười dùng được mô tả dưới dạng các kiểu con được kết nối bằng các dòng tương ứng và biểu tượng độc quyền với Party , siêu kiểu.

Các Party.PartyTypeCode sở hữu là viết tắt của subtype phân biệt , ví dụ, nó cho thấy đó loại dụ kiểu phụ phải bổ sung một sự xuất hiện siêu kiểu nhất định.

Ngoài ra, Đảng được kết nối với danh sách nhạc thông qua OwnerId tài sản đó được mô tả như một FOREIGN KEY trỏ đến Party.PartyId . Theo cách này, Bên liên quan (a) Danh sách phát với (b) Nhóm và (c) Người dùng .

Theo đó, do một cá thể của một Bên cụ thể là Nhóm hoặc Người dùng , nên một Danh sách phát cụ thể có thể được liên kết với tối đa một lần xuất hiện.

Bố cục mức logic minh họa

Sơ đồ IDEF1X đã được trình bày trước đây đã phục vụ tôi như một nền tảng để tạo ra sự sắp xếp SQL-DDL hợp lý sau (và tôi đã cung cấp các ghi chú dưới dạng các nhận xét nêu bật một số điểm có liên quan cụ thể của Wapeg, khai báo ràng buộc ràng buộc):

-- You should determine which are the most fitting 
-- data types and sizes for all your table columns 
-- depending on your business context characteristics.

-- Also, you should make accurate tests to define the 
-- most convenient INDEX strategies based on the exact 
-- data manipulation tendencies of your business domain.

-- As one would expect, you are free to utilize 
-- your preferred (or required) naming conventions. 

CREATE TABLE PartyType ( -- Represents an independent entity type.
    PartyTypeCode CHAR(1)  NOT NULL,
    Name          CHAR(30) NOT NULL,  
    --
    CONSTRAINT PartyType_PK PRIMARY KEY (PartyTypeCode),
    CONSTRAINT PartyType_AK UNIQUE      (Name)  
);

CREATE TABLE Party ( -- Stands for the supertype.
    PartyId         INT       NOT NULL,
    PartyTypeCode   CHAR(1)   NOT NULL, -- Symbolizes the discriminator.
    CreatedDateTime TIMESTAMP NOT NULL,  
    --
    CONSTRAINT Party_PK            PRIMARY KEY (PartyId),
    CONSTRAINT PartyToPartyType_FK FOREIGN KEY (PartyTypeCode)
        REFERENCES PartyType (PartyTypeCode)
);

CREATE TABLE UserProfile ( -- Denotes one of the subtypes. 
    UserId     INT      NOT NULL, -- To be constrained as both (a) the PRIMARY KEY and (b) a FOREIGN KEY.
    UserName   CHAR(30) NOT NULL,  
    FirstName  CHAR(30) NOT NULL,
    LastName   CHAR(30) NOT NULL,
    GenderCode CHAR(3)  NOT NULL,
    BirthDate  DATE     NOT NULL,
    --
    CONSTRAINT UserProfile_PK  PRIMARY KEY (UserId),
    CONSTRAINT UserProfile_AK1 UNIQUE ( -- Multi-column ALTERNATE KEY.
        FirstName,
        LastName,
        GenderCode,
        BirthDate
    ),
    CONSTRAINT UserProfile_AK2       UNIQUE (UserName), -- Single-column ALTERNATE KEY.
    CONSTRAINT UserProfileToParty_FK FOREIGN KEY (UserId)
        REFERENCES Party (PartyId)
);

CREATE TABLE MyGroup ( -- Represents the other subtype.
    GroupId INT      NOT NULL, -- To be constrained as both (a) the PRIMARY KEY and (b) a FOREIGN KEY.
    Title   CHAR(30) NOT NULL,
    --
    CONSTRAINT Group_PK        PRIMARY KEY (GroupId),
    CONSTRAINT Group_AK        UNIQUE      (Title), -- ALTERNATE KEY.
    CONSTRAINT GroupToParty_FK FOREIGN KEY (GroupId)
        REFERENCES Party (PartyId)
);

CREATE TABLE Playlist ( -- Stands for an independent entity type.
    PlaylistId      INT       NOT NULL,
    OwnerId         INT       NOT NULL,  
    Title           CHAR(30)  NOT NULL,
    CreatedDateTime TIMESTAMP NOT NULL,  
    --
    CONSTRAINT Playlist_PK     PRIMARY KEY (PlaylistId),
    CONSTRAINT Playlist_AK     UNIQUE      (Title),  -- ALTERNATE KEY.
    CONSTRAINT PartyToParty_FK FOREIGN KEY (OwnerId) -- Establishes the relationship with (a) the supertype and (b) through the subtype with (c) the subtypes.
        REFERENCES Party (PartyId)
);

CREATE TABLE GroupMember ( -- Denotes an associative entity type.
    MemberId       INT       NOT NULL, 
    GroupId        INT       NOT NULL,
    IsOwner        BOOLEAN   NOT NULL,    
    JoinedDateTime TIMESTAMP NOT NULL,
    --        
    CONSTRAINT GroupMember_PK              PRIMARY KEY (MemberId, GroupId), -- Composite PRIMARY KEY.
    CONSTRAINT GroupMemberToUserProfile_FK FOREIGN KEY (MemberId)
        REFERENCES UserProfile (UserId),
    CONSTRAINT GroupMemberToMyGroup_FK     FOREIGN KEY (GroupId)
        REFERENCES MyGroup (GroupId)  
);

Tất nhiên, bạn có thể thực hiện một hoặc nhiều điều chỉnh để tất cả các đặc điểm của bối cảnh kinh doanh của bạn được thể hiện với độ chính xác cần thiết trong cơ sở dữ liệu thực tế.

Lưu ý : Tôi đã thử nghiệm cách bố trí logic ở trên trên db <> fiddle này và cả trên Fiddle SQL này , cả hai đều chạy hệ điều hành trên PostgreQuery 9.6, để bạn có thể thấy chúng trong trò chơi hành động.

Sên

Như bạn thấy, tôi đã không bao gồm Group.Slugcũng Playlist.Slugnhư các cột trong tờ khai DDL. Điều này là như vậy bởi vì, phù hợp với giải thích sau đây của bạn

Đây sluglà những phiên bản duy nhất, chữ thường, gạch nối của thực thể tương ứng title. Ví dụ: a groupvới title'Nhóm thử nghiệm' sẽ có slug'nhóm thử nghiệm'. Các bản sao được nối với số nguyên tăng dần. Điều này sẽ thay đổi bất cứ lúc nào thay đổi của họ title. Tôi tin rằng điều đó có nghĩa là họ sẽ không tạo ra các khóa chính tuyệt vời? Có, slugsusernameslà duy nhất trong các bảng tương ứng của họ.

người ta có thể kết luận rằng các giá trị của chúng là có thể tạo được (nghĩa là chúng phải được tính toán hoặc tính toán theo các giá trị tương ứng Group.TitlePlaylist.Titlegiá trị, đôi khi kết hợp với giả định, một số loại INTEGERs do hệ thống tạo ra), vì vậy tôi sẽ không khai báo các cột đã nói trong bất kỳ bảng cơ sở nào vì chúng sẽ giới thiệu các bất thường cập nhật.

Ngược lại, tôi sẽ sản xuất Slugs

  • có thể, theo quan điểm , (a) bao gồm đạo hàm của các giá trị đó trong các cột ảo và (b) có thể được sử dụng trực tiếp trong các hoạt động CHỌN tiếp theo, có thể thu được phần INTEGER, ví dụ, bằng cách kết hợp giá trị của (1) các Playlist.OwnerIdvới (2) có dấu gạch nối trung gian và (3) giá trị của Playlist.Title;

  • hoặc, nhờ mã chương trình ứng dụng, bắt chước cách tiếp cận được mô tả trước đó (có thể là thủ tục), một khi các bộ dữ liệu thích hợp được truy xuất và định dạng để giải thích cho người dùng cuối.

Theo cách này, bất kỳ của những hai phương pháp sẽ tránh cơ chế “cập nhật đồng bộ hóa” mà phải được đưa ra khi và chỉ khi những Slugsđược giữ lại trong các cột của các bảng cơ sở.

Cân nhắc tính toàn vẹn và nhất quán

Điều quan trọng cần đề cập là (i) mỗi Party hàng phải được bổ sung mọi lúc bởi (ii) đối tác tương ứng trong chính xác một trong các bảng biểu thị cho các kiểu con, trong đó (iii) phải Tuân theo giá trị có trong Party.PartyTypeCodecột Giáo dục phân biệt đối xử.

Sẽ khá thuận lợi khi thực thi loại tình huống đó theo cách khai báo , nhưng không có hệ thống quản lý cơ sở dữ liệu SQL chính nào (bao gồm Postgres) đã cung cấp các công cụ cần thiết để tiến hành như vậy; do đó, viết mã thủ tục trong GIAO DỊCH ACID cho đến nay là lựa chọn tốt nhất để đảm bảo rằng các trường hợp được mô tả trước đây luôn được đáp ứng trong cơ sở dữ liệu của bạn. Khả năng khác sẽ là dùng đến TRIGGERS, nhưng họ có xu hướng làm cho mọi thứ không gọn gàng, để nói.

Trường hợp so sánh

Nếu bạn muốn thiết lập một số tương tự, bạn có thể quan tâm đến việc xem câu trả lời của tôi cho các câu hỏi (mới hơn) có tên

kể từ khi kịch bản so sánh được thảo luận.


Chú thích

1 Bên là một thuật ngữ được sử dụng trong bối cảnh pháp lý khi đề cập đến một cá nhân hoặc một nhóm các cá nhân sáng tác một thực thể duy nhất , vì vậy mệnh giá này phù hợp để thể hiện các khái niệm về Người dùng Nhóm liên quan đến môi trường kinh doanh.

2 Định nghĩa tích hợp cho mô hình hóa thông tin ( IDEF1X ) là một kỹ thuật mô hình hóa dữ liệu rất được khuyến khích, được thành lập như một tiêu chuẩn vào tháng 12 năm 1993 bởi Viện Tiêu chuẩn và Công nghệ Quốc gia Hoa Kỳ(NIST). Nó hoàn toàn dựa trên (a) một số tác phẩm lý thuyết ban đầu được tác giả bởi người khởi tạo duy nhất của mô hình quan hệ , tức là, Tiến sĩ EF Codd ; trên (b) quan điểm về mối quan hệ thực thể , được phát triển bởi Tiến sĩ PP Chen ; và cũng trên (c) Kỹ thuật thiết kế cơ sở dữ liệu logic, được tạo bởi Robert G. Brown.


Tôi không thấy bất kỳ ràng buộc nào cho bữa tiệc chính xác là một trong những người dùng hoặc nhóm
Jasen

Có vẻ như bình luận của bạn phải được thực hiện với các trích đoạn câu hỏi sau (cả hai đều có trong phần có tiêu đề Tính toàn vẹn và tính nhất quán của
Hồi giáo

Nó là rất quan trọng kể rằng (i) mỗi Partyhàng phải được bổ sung bất cứ lúc nào bằng cách (ii) các đối tác tương ứng trong chính xác một trong các bảng đứng cho các phân nhóm, trong đó (iii) phải 'tuân thủ' giá trị chứa trong Party.PartyTypeCodecột -denoting các discriminator- ”.
MDCCL

Nó sẽ là khá thuận lợi để thi hành mà loại tình huống trong một khai báo cách, nhưng không ai trong số các hệ thống quản lý cơ sở dữ liệu SQL lớn (bao gồm cả Postgres) đã cung cấp cần thiết cụ để tiến hành như thế; do đó, viết thủ tục trong GIAO DỊCH ACID cho đến nay là lựa chọn tốt nhất để đảm bảo rằng các trường hợp được mô tả trước đây luôn được đáp ứng trong cơ sở dữ liệu của bạn. Khả năng khác sẽ là dùng đến TRIGGERS, nhưng họ có xu hướng làm cho mọi thứ trở nên không gọn gàng, vì vậy để nói chuyện .
MDCCL

Do đó, một khi (hy vọng sớm) cung cấp Postgres, giả sử, ĐÁNH GIÁ, tôi sẽ rất vui khi bao gồm các ràng buộc (khai báo) áp dụng. Hiện tại, hai cách tiếp cận do DBMS cung cấp được đề xuất ở trên.
MDCCL
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.