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ùng và Danh sách phát và (b) giữa Nhóm và Danh sách phát khá giống nhau, nên thực tế này cho thấy Người dùng và Nhóm là cá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:
Như đã trình bày, Nhóm và Ngườ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.Slug
cũng Playlist.Slug
như 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 slug
là 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 group
vớ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ó, slugs
và usernames
là 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.Title
và Playlist.Title
giá 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.OwnerId
vớ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.PartyTypeCode
cộ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 và 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.