6

Tôi có một bảng ASSETS rằng có một cấu trúc như nó được hiển thị dưới đây:Chỉ định khoá ngoại trên một cột và giá trị của cột khác

---------------------------------------------------- 
ID (PK) | DESCRIPTION | TYPE | Do- | Do+ | Dx- | Dx+ 
---------------------------------------------------- 

TYPE cột có một nước ngoài chủ chốt, giá trị có thể là SECURITY hoặc CURRENCY (tức FX), tôi cũng có thêm hai bảng: CURRENCIES (ví dụ, EUR, RUB hoặc USD):

-------------------------------------------------------- 
ID (PK)| FROM (FK ASSETS.ID) | TO (FK ASSETS.ID) | VALUE 
-------------------------------------------------------- 

SECURITIES (ví dụ, MTS, GAZP hoặc VTB):

---------------------------------------------------------- 
ID (PK)(FK ASSETS.ID)| CURRENCY (PK)(FK ASSETS.ID) | VALUE 
---------------------------------------------------------- 

Làm thế nào tôi có thể làm cho một hạn chế, đó không chỉ đóng vai trò như chìa khóa nước ngoài tại CURRENCIES.FROM, CURRENCIES.TOSECURITIES.CURRENCY, nhưng cũng kiểm tra xem có giới thiệu ASSETS.TYPECURRENCY và trong SECURITIES cũng kiểm tra xem có giới thiệu ASSETS.TYPE cho SECURITIES.IDSECURITY không?

Tôi đoán tôi có thể viết trình kích hoạt để kiểm tra giá trị ASSETS.TYPE, nhưng tôi đang tìm kiếm giải pháp khác ngay bây giờ (nếu có thể, tất nhiên là).

Nếu có cách tốt hơn để thực hiện những điều mong muốn (như thiết kế cơ sở dữ liệu tốt hơn), vui lòng chia sẻ ý tưởng của bạn.

P.S. Tôi đoán nó là một vấn đề khá phổ biến, vì vậy nếu có các bài viết về nó hoặc các câu hỏi tương tự được hỏi trên mạng này hoặc một số giải pháp tổng hợp, hãy chia sẻ.

+0

Xem câu trả lời của tôi [ở đây] (https: // stackoverflow.com/a/26093733/3404097). (Câu hỏi cụ thể một cách bối rối một phần không có bảng Sinh viên (ASSESTS_DATA) của bạn trong văn bản gốc của nó nhưng có một trong sơ đồ Chỉnh sửa của nó.) Thiết kế đầu tiên của bạn giống như tôi đề xuất (liên quan đơn giản) (bộ đầu tiên) và của bạn được sửa đổi/KIỂM TRA như tôi đề nghị (tập thứ hai của đạn) – philipxy

+0

@philipxy: như tôi đã gắn thẻ câu hỏi của tôi, FireBird. – potashin

+0

Nhìn thoáng qua, có vẻ lạ khi tôi đối xử với Chứng khoán và Tiền tệ chỉ bằng hai loại tài sản. Một (Security) là một thứ có giá trị - có thể là một tòa nhà, một chứng chỉ nợ hay bất cứ thứ gì - trong khi cái kia (tiền tệ) chỉ là một đơn vị đo lường. Tôi muốn vài chứng khoán và * Tiền *, với Tiền là tiền mặt trong các loại tiền tệ khác nhau, tiền trong các tài khoản ngân hàng khác nhau, v.v. –

Trả lời

4

trả lời cho câu hỏi ban đầu của bạn là sử dụng thêm CHECKchế như:

CREATE TABLE CURRENCIES (
    ... 
    CONSTRAINT c_asset_from CHECK(exists(select 1 from ASSETS a where a.id = from and a.type = 'CURRENCY')) 
); 

Và constraion tương tự cho TO lĩnh vực và trong SECURITIES cho CURRENCY lĩnh vực.
Nhưng tôi nghĩ rằng thiết kế mới của bạn, với riêng biệt FK cho securitycurrency, là thiết kế tốt hơn.

1

Bạn có thể sử dụng séc cho việc này. Bạn có muốn mã hóa các giá trị này không?

CREATE TABLE Persons 
(
    P_Id int NOT NULL, 
    LastName varchar(255) NOT NULL, 
    FirstName varchar(255), 
    Address varchar(255), 
    City varchar(255), 
    CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes') 
) 

Nguồn: W3schools

Và sử dụng Firebird có thể yêu cầu cú pháp khác nhau. Hãy xem tại địa chỉ: Firebird reference

+0

Cú pháp 'CHECK' của Firebird giống nhau. –

+0

Trong ví dụ của bạn, bạn kiểm tra các cột của cùng một bảng, nhưng bạn có thể cung cấp một ví dụ trỏ đến giá trị của cột từ một bảng khác không? – potashin

+0

@notulysses Trong trường hợp đó, bạn có thể tốt hơn với việc xem xét lại mô hình của bạn hoặc sử dụng trình kích hoạt. –

1

Bạn có thể làm điều đó một cách khai báo bằng cách thay đổi thiết kế khóa của bạn và sử dụng xác định mối quan hệ.

Đây là kế hoạch chi tiết:

enter image description here

Nhìn cách ASSET.ASSET_TYPE được lan truyền thông qua cả hai "chi nhánh", chỉ để được sáp nhập trong SECURITY.ASSET_TYPE.

SECURITY.ASSET_TYPE chỉ là một trường, một hàng SECURITY không bao giờ có thể kết nối với nhiều loại nội dung. Để nói hơi khác: nếu ASSETCURRENCY được kết nối với cùng một SECURITY, chúng phải có cùng một ASSET_TYPE.

Ngoài ra, CURRENCY không bao giờ có thể trỏ đến ASSET s loại khác nhau.

Bạn có thể mang lại chìa khóa thay thế cũ của bạn (và các lĩnh vực khác) vào mô hình này khi cần thiết.


Điều đó đang được nói, tạo ra ASSET_NO trình bày một số thách thức.

  • Bạn chỉ có thể sử dụng auto-incrementing cơ chế tích hợp vào DBMS của bạn, nhưng điều đó sẽ để lại "lỗ" (nghĩa là hai loại tài sản khác nhau sẽ không bao giờ sử dụng các số nguyên cùng, mặc dù họ có thể về mặt kỹ thuật). Hoặc bạn có thể tìm giá trị tiếp theo theo cách thủ công, nhưng bạn sẽ phải xử lý đồng thời trong trường hợp đó (chèn tuần tự thông qua khóa hoặc thử lại trong trường hợp giao dịch đồng thời đã thử cùng một giá trị).
2

IMO về mặt kỹ thuật thiết kế có thể bị chỉ trích trong hai loại:

  • Có một chìa khóa nước ngoài mục đích kép trong bảng Asset gọi type (Polymorphic Association anti-pattern).
    Điều đó sẽ vi phạm biểu mẫu bình thường đầu tiên (nguyên nhân vấn đề), mất tính toàn vẹn tham chiếu.
    Một giải pháp có thể là đơn giản hóa mối quan hệ bằng cách thừa kế.
    Có bảng cơ sở cho bảng Tiền tệ và An ninh được gọi là Money, chứa các thuộc tính được chia sẻ của chúng, như name.
    khóa chính của bảng Tiền sẽ là khóa chính của các bảng CurrencySecurity.
    Có khóa ngoại là Money bên trong Asset sẽ là giải pháp.
  • Sử dụng surrogate identifier trên bảng nội dung, điều này sẽ dẫn đến việc mất mất logic nghiệp vụ trong thiết kế lược đồ.
    Tôi muốn có khóa chính kết hợp trong Bảng nội dung PK{ID, TYPE(money fk)}.
    Sau đó, có ràng buộc kiểm tra trên CURRENCIESSECURITIES sẽ giải quyết vấn đề .
    CURRENCIES_chk {FK.CURRENCY = FK_TO.Money && FK.CURRENCY = FK_FROM.Money} SECURITIES_chk {FK.SECURITY = FK.Money}

    enter image description here
+0

Có một ý tưởng như: bảng 'ASSET_TYPE' (một trường' ID', các giá trị có thể 'SECURITY' /' CURRENCY'), bảng 'MONEY' (không phải là một lựa chọn tên tốt cho bảng này, nhưng trong sự tương thích với câu trả lời của bạn, tôi để nguyên nó) (hai trường, 'ID',' TYPE' ('FK' thành' ASSET_TYPE.ID')). Và một trình kích hoạt để chèn vào trong bảng 'SECURITIES' hoặc' CURRENCIES' ('FX', chọn đúng từ) khi' MONEY.TYPE'. Tôi đoán tôi có thể sử dụng chỉ một kích hoạt để giải quyết vấn đề đó. Trong thiết kế của bạn, tôi chỉ thấy một luồng: Tôi có thể đặt các chứng khoán như 'GAZP' trong bảng' CURRENCY' và ngược lại. – potashin

+0

Xin lỗi vì tiếng Anh nghèo nàn của tôi. Trong câu trả lời của tôi không có bất kỳ cơ chế Kích hoạt nào, chỉ có hai ràng buộc kiểm tra tồn tại! Có thể tôi chưa hiểu miền của thiết kế của bạn. cho phép một kịch bản từng bước một để xem điều gì sẽ xảy ra. Đầu tiên chúng ta định nghĩa 'GAZP' là một hàng trong Security? –

+0

Tôi không nghĩ rằng bạn chưa hiểu khái niệm, tôi chỉ không biết làm thế nào để đảm bảo rằng chứng khoán sẽ không đi đến bảng tiền tệ (aka fx) và ngược lại. Ngoài ra, tất cả họ nên ở trong bảng tiền. – potashin

Các vấn đề liên quan