Về mặt khái niệm, mặc dù trong môi trường kinh doanh của bạn, Thứ tự và Địa chỉ là những ý tưởng được liên kết chặt chẽ, chúng có hiệu lực với hai loại thực thể riêng biệt, mỗi loại có các thuộc tính (hoặc thuộc tính) riêng và các ràng buộc.
Do đó, như đã nêu trong các nhận xét, tôi đồng ý với @Erik và bạn nên tổ chức bố cục logic của khai báo cơ sở dữ liệu của mình trong số các yếu tố khác:
- một bảng riêng biệt để giữ các mẩu thông tin Địa chỉ ;
- một bảng để giữ lại các chi tiết cụ thể của khách hàng ;
- một bảng để bao gồm các điểm dữ liệu thứ tự ; và
- một bảng để chứa thông tin về mối liên hệ giữa (các) Khách hàng và Địa chỉ ;
như tôi sẽ làm gương dưới đây
Sơ đồ IDEF1X tiếp xúc
Một bức tranh đáng giá cả ngàn từ, vì vậy tôi đã tạo sơ đồ IDEF1X được hiển thị trong Hình 1 để minh họa một số khả năng được mở theo đề xuất của tôi:
Khách hàng , địa chỉ và các hiệp hội của họ
Như đã chứng minh, tôi đã mô tả một liên kết với tỷ lệ số lượng nhiều-nhiều (M: N) giữa các loại thực thể Khách hàng a và Địa chỉ ; Cách tiếp cận này sẽ mang lại sự linh hoạt trong tương lai bởi vì, như bạn biết, Khách hàng có thể giữ nhiều Địa chỉ theo thời gian hoặc thậm chí đồng thời và cùng một Địa chỉ có thể được chia sẻ bởi nhiều Khách hàng .
Một đặc biệt Địa chỉ có thể được sử dụng theo nhiều cách bởi một-nhiều (1: M) Khách hàng ; ví dụ: nó có thể được định nghĩa là Vật lý và / hoặc có thể được đặt cho Giao hàng và / hoặc cho Thanh toán . Có lẽ, cùng một địa chỉ Địa chỉ có thể phục vụ từng mục đích đã nói ở trên cùng một lúc hoặc có thể bao gồm hai mục đích sử dụng trong khi một địa chỉ khác nhau xuất hiện trong các mục đích còn lại.
a Trong một số môi trường kinh doanh, Khách hàng có thể là Cá nhân hoặc Tổ chức (tình huống ngụ ý một sự sắp xếp hơi khác biệt, như chi tiết trong câu trả lời này về cấu trúc siêu kiểu phụ) nhưng với mục tiêu cung cấp một ví dụ đơn giản, tôi đã quyết định không bao gồm khả năng đó ở đây. Trong trường hợp bạn cần bao gồm tình huống đó trong cơ sở dữ liệu của mình, bài đăng của liên kết trước đó hiển thị phương pháp để giải quyết yêu cầu đã nói.
Đặt hàng , địa chỉ , vai trò khách hàng và địa chỉ
Thông thường, một Đơn hàng chỉ yêu cầu hai loại Địa chỉ , một cho Giao hàng và một cho Thanh toán . Theo cách này, cùng một thể hiện Địa chỉ có thể điền vào cả hai Vai trò cho một Đơn hàng riêng lẻ , nhưng mỗi Vai trò được hình dung bởi thuộc tính tương ứng, tức là ShippingAddressId hoặc BillingAddressId .
Đơn hàng được kết nối với Địa chỉ thông qua loại thực thể liên kết CustomerAddress với sự trợ giúp của hai khóa NGOẠI TỆ đa tài sản, nghĩa là,
- (Số khách hàng , ShippingAddressId ) và (Số khách hàng , BillingAddressId ),
cả hai đều trỏ đến KEY PRIMARY đa tài sản của khách hàng được hiển thị dưới dạng
- ( CustomerNumber , AddressID )
Sự giúp đỡ thể hiện một quy tắc kinh doanh quy định rằng (a) một thể hiện Đơn hàng phải được liên kết riêng với (b) Địa chỉ xuất hiện trước đây được liên kết với Khách hàng cụ thể đã thực hiện Đơn hàng đó và không bao giờ với (c) một Khách hàng ngẫu nhiên - Địa chỉ liên quan .
Lịch sử cho (1) Địa chỉ và cho (2) hiệp hội Khách hàng Địa chỉ
Nếu bạn muốn cung cấp khả năng sửa đổi các mẩu thông tin Địa chỉ , thì bạn phải theo dõi tất cả các thay đổi dữ liệu. Theo cách này, tôi mô tả Địa chỉ như một “có thể kiểm tra” loại thực thể duy trì riêng của mình AddressHistory .
Vì bản chất của một kết nối giữa một Khách hàng và Địa chỉ cũng có thể chịu một hoặc nhiều sửa đổi, tôi cũng đã mô tả khả năng xử lý của một hiệp hội như một đối tượng có thể kiểm tra được bởi một loại hình thực thể của khách hàng .
Về mặt này, các yếu tố khác nhau xử lý trong Q & A không. 1 và hỏi đáp không. 2 , Wapboth về việc kích hoạt các khả năng tạm thời trong cơ sở dữ liệu.
Bố cục logic SQL-DDL minh họa
Do đó, về mặt sơ đồ được hiển thị và giải thích ở trên, tôi đã khai báo cách sắp xếp mức logic sau (bạn có thể điều chỉnh để đáp ứng chính xác nhu cầu của mình):
-- 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 Customer (
CustomerNumber INT NOT NULL,
SpecificAttribute CHAR(30) NOT NULL,
ParticularAttribute CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Customer_PK PRIMARY KEY (CustomerNumber)
);
CREATE TABLE Address (
AddressId INT NOT NULL,
SpecificAttribute CHAR(30) NOT NULL,
ParticularAttribute CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Address_PK PRIMARY KEY (AddressId)
);
CREATE TABLE CustomerAddress (
CustomerNumber INT NOT NULL,
AddressId INT NOT NULL,
IsPhysical BIT NOT NULL,
IsShipping BIT NOT NULL,
IsBilling BIT NOT NULL,
IsActive BIT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT CustomerAddress_PK PRIMARY KEY (CustomerNumber, AddressId),
CONSTRAINT CustomerAddressToCustomer_FK FOREIGN KEY (CustomerNumber)
REFERENCES Customer (CustomerNumber),
CONSTRAINT CustomerAddressToAddress_FK FOREIGN KEY (AddressId)
REFERENCES Address (AddressId)
);
CREATE TABLE MyOrder (
CustomerNumber INT NOT NULL,
OrderNumber INT NOT NULL,
ShippingAddressId INT NOT NULL,
BillingAddressId INT NOT NULL,
SpecificAttribute CHAR(30) NOT NULL,
ParticularAttribute CHAR(30) NOT NULL,
OrderDate DATE NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Order_PK PRIMARY KEY (CustomerNumber, OrderNumber),
CONSTRAINT OrderToCustomer_FK FOREIGN KEY (CustomerNumber)
REFERENCES Customer (CustomerNumber),
CONSTRAINT OrderToShippingAddress_FK FOREIGN KEY (CustomerNumber, ShippingAddressId)
REFERENCES CustomerAddress (CustomerNumber, AddressId),
CONSTRAINT OrderToBillingAddress_FK FOREIGN KEY (CustomerNumber, BillingAddressId)
REFERENCES CustomerAddress (CustomerNumber, AddressId)
);
CREATE TABLE AddressHistory (
AddressId INT NOT NULL,
AuditedDateTime DATETIME NOT NULL,
SpecificAttribute CHAR(30) NOT NULL,
ParticularAttribute CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT AddressHistory_PK PRIMARY KEY (AddressId, AuditedDateTime),
CONSTRAINT AddressHistoryToAddress_FK FOREIGN KEY (AddressId)
REFERENCES Address (AddressId)
);
CREATE TABLE CustomerAddressHistory (
CustomerNumber INT NOT NULL,
AddressId INT NOT NULL,
AuditedDateTime DATETIME NOT NULL,
IsPhysical BIT NOT NULL,
IsShipping BIT NOT NULL,
IsBilling BIT NOT NULL,
IsActive BIT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT CustomerAddressHistory_PK PRIMARY KEY (CustomerNumber, AddressId, AuditedDateTime),
CONSTRAINT CustomerAddressHistoryToCustomerAddress_FK FOREIGN KEY (CustomerNumber, AddressId)
REFERENCES CustomerAddress (CustomerNumber, AddressId)
);
Nếu bạn muốn xem, tôi đã thử nó trong db <> fiddle này chạy trên SQL Server 2017.
Các History
bảng
Đoạn trích sau từ câu hỏi của bạn là rất quan trọng:
Điều tôi đang tìm kiếm là làm thế nào tôi có thể thiết lập địa chỉ của mình để khi tôi chỉnh sửa chúng, đơn hàng không bị ảnh hưởng bởi thực tế là khách hàng cập nhật địa chỉ của mình hoặc chuyển địa điểm.
Các bảng AddressHistory
và CustomerAddressHistory
trợ giúp trong việc đảm bảo Đơn hàng không bị ảnh hưởng bởi Địa chỉ thay đổi , vì tất cả các hàng trước đó của LÊN nên được giữ lại trong History
bảng tương ứng và có thể được truy vấn khi cần thiết. Các hoạt động CẬP NHẬT và XÓA trên hai bảng này nên bị cấm (cố gắng thay đổi lịch sử thậm chí có thể có ý nghĩa pháp lý tiêu cực).
Các Interval bao trùm giữa các giá trị kèm theo trong AddressHistory.CreatedDateTime
và AddressHistory.AuditedDateTime
đại diện cho toàn bộ giai đoạn trong đó một “quá khứ” nhất địnhAddress
hàng được coi là “có mặt”, “hiện tại” hoặc “hiệu quả”. Cân nhắc tương tự áp dụng cho các CustomerAddressHistory
hàng.
Cột CustomerAddress.IsActive
BIT (boolean) có nghĩa là chỉ ra liệu một Address
hàng nhất định có phải là có thể sử dụng được bởi một Customer
hàng hay không; ví dụ: nếu được đặt thành 'sai', nó sẽ truyền đạt thực tế rằng Khách hàng sẽ không sử dụng Địa chỉ đó nữa và do đó không thể sử dụng cho Đơn hàng mới .
Lưu ý : Mặt khác, tôi đã thấy một số hệ thống trong đó mỗi lần Đơn hàng mới được kích hoạt, thông tin Địa chỉ phải được nhập (một số lần lặp lại) và (các) Địa chỉ được sử dụng cho Đơn hàng trước đây không bao giờ bị xóa (do đó các đơn đặt hàng không bị ảnh hưởng bởi Địa chỉ thay đổi).
Quá trình hành động này có thể quyết định liên quan đến khối lượng dư thừa đáng kể, nhưng có khả năng là việc phụ thuộc vào các yêu cầu thông tin chính xác của lĩnh vực kinh doanh của bạn có thể hoạt động, vì vậy bạn cũng có thể đánh giá ưu và nhược điểm của nó.
Phục hồi dữ liệu
Phiên bản hiện tại, hiện tại, phiên bản hiện tại và hiệu quả của một sự xuất hiện của Địa chỉ phải được chứa dưới dạng một hàng trong Address
bảng, nhưng CHỌN các trạng thái trước đó của một địa chỉ TỪ AddressHistory
(hoặc từCustomerAddressHistory
) là dễ dàng và có thể là một bài tập thú vị để nâng cao kỹ năng mã hóa SQL của bạn.
Đối với một trong những tình huống mà bạn đã đề cập trong các nhận xét, nếu bạn muốn truy xuất phiên bản thứ hai đến phiên bản cuối cùng của một Address
hàng riêng lẻ TỪ AddressHistory
, bạn phải tính đến MAX(AddressHistory.AuditedDateTime)
vàAddressHistory.AddressId
phù hợp với đặc biệt Address.AddressId
giá trị trong tầm tay.
Về vấn đề này, ít nhất là khi xây dựng cơ sở dữ liệu quan hệ , rất thuận tiện để xác định sơ đồ khái niệm tương ứng (dựa trên các quy tắc kinh doanh áp dụng ) và sau đó tuyên bố sắp xếp DDL hợp lý tiếp theo . Khi bạn có được các phiên bản ổn định và đáng tin cậy của các yếu tố cơ bản này (tất nhiên, có thể phát triển theo thời gian), đã đến lúc phân tích và xác định các cách tốt nhất để thao tác (thông qua các hoạt động INSERT, UPDATE, DELETE và SELECT hoặc kết hợp chúng) liên quan đến dữ liệu.
Nhận thức, quan điểm và hỗ trợ (các) chương trình ứng dụng của người dùng cuối
Rõ ràng, ở mức độ trừu tượng bên ngoài , thông tin Địa chỉ được người dùng cuối coi là một phần của Đơn hàng và không có gì sai với điều đó, nhưng điều đó không có nghĩa là các nhà lập mô hình phải thiết kế các phần quan trọng của cơ sở dữ liệu trong câu hỏi như thế. Vào thời điểm này, nếu có nhu cầu, ví dụ, in Đơn hàng đầy đủ (rất khả thi), bạn có thể sao chép lại theo yêu cầu với sự trợ giúp của một vài toán tử THAM GIA và các mệnh đề WHERE (xem xét thời hạn hiệu lực liên quan , v.v.) có thể cố định trong lượt xem để tiêu thụ trong tương lai, gửi tập kết quả thích hợp đến (các) chương trình ứng dụng liên quan, đến lượt nó, có thể nâng cao định dạng của nó khi cần thiết.
Tất nhiên, (các) chương trình ứng dụng cũng sẽ rất hữu ích khi Đơn hàng đang được thực hiện; ví dụ: cửa sổ ứng dụng dành cho máy tính để bàn / thiết bị di động hoặc trang web có thể:
- chỉ hiển thị (các) Địa chỉ mà Khách hàng có liên quan đã thiết lập là có thể sử dụng được (thông qua
CustomerAddress.IsActive
);
- liệt kê tất cả các Địa chỉ mà Khách hàng đã kích hoạt cho dịch vụ thanh toán (thông qua
CustomerAddress.IsBilling
); và
- nhóm tất cả các Địa chỉ mà Khách hàng đã xác định cho dịch vụ vận chuyển (thông qua
CustomerAddress.IsShipping
);
tạo điều kiện theo cách này tất cả các quy trình liên quan tại GUI (nghĩa là mức độ trừu tượng bên ngoài của một hệ thống máy tính).
Cách đọc được đề nghị
Bạn đã yêu cầu (hiện đã xóa các bình luận) một số gợi ý về tài liệu cơ sở dữ liệu âm thanh; do đó, đối với tài liệu lý thuyết , tôi khuyên bạn nên đọc tất cả các tác phẩm được viết bởi Tiến sĩ EF Codd , người nhận Giải thưởng Turing và, tất nhiên, người khởi tạo duy nhất của mô hình dữ liệu quan hệ (có thể phù hợp hơn bao giờ hết). Danh sách này bao gồm một số bài báo và giấy tờ có ảnh hưởng rất lớn của ông.
Chính xác, hai tác phẩm quan trọng không có trong danh sách nói trên là Bài giảng Giải thưởng ACM Turing của ông có tên Cơ sở dữ liệu quan hệ: Một nền tảng thực tiễn cho năng suất , từ năm 1981, và cuốn sách của ông có tên là Mô hình quan hệ để quản lý cơ sở dữ liệu: Phiên bản 2 , đã được xuất bản vào năm 1990.
Về mặt thiết kế khái niệm , Định nghĩa tích hợp cho mô hình hóa thông tin (IDEF1X) là một kỹ thuật được khuyến nghị nghiêm túc, được định nghĩa là 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).