2016-01-13 90 views
0

這裏是我的情況:我有如何創建一個表,其行的引用2個現有表中的1個(並且只有1個)?

CREATE DATABASE JsPracticeDb; 
/* Create tables corresponding to the problems, solutions to 
    problems, and ratings of problems or solutions */ 
CREATE TABLE Problems ( 
    id INT PRIMARY KEY NOT NULL, 
    prompt_code VARCHAR(3000), 
    test_func_code VARCHAR(3000), 
    test_input_code VARCHAR(3000) 
); 
CREATE TABLE Solutions (
    id INT PRIMARY KEY NOT NULL, 
    problem_id INT, 
    solver_name VARCHAR(50), 
    code VARCHAR(3000), 
    FOREIGN KEY (problem_id) REFERENCES Problems(id) ON DELETE CASCADE, 
); 

創建了兩個表,我想關於評級Solutions,這是我寫的

CREATE TABLE Ratings (
    id INT PRIMARY KEY NOT NULL, 
    solution_id INT, 
    stars TINYINT, 
    FOREIGN KEY (solution_id) REFERENCES Solutions(id) ON DELETE CASCADE 
); 

但後來我意識到我可能真的要創建一個表也有​​的評價。在「蠻力」解決方案,在我看來,是

CREATE TABLE SolutionRatings (
    id INT PRIMARY KEY NOT NULL, 
    solution_id INT, 
    stars TINYINT, 
    FOREIGN KEY (solution_id) REFERENCES Solutions(id) ON DELETE CASCADE 
); 
CREATE TABLE ProblemRatings (
    id INT PRIMARY KEY NOT NULL, 
    problem_id INT, 
    stars TINYINT, 
    FOREIGN KEY (problem_id) REFERENCES Problems(id) ON DELETE CASCADE 
); 

但我的直覺編程說有一個與我用複製粘貼寫的代碼兩個部分是幾乎相同的事實問題。但是,我想不出任何使用交叉表或類似的替代解決方案,它也允許我執行級聯刪除。例如,我知道我能做到

CREATE TABLE RatedTables (
    id TINYINT PRIMARY KEY NOT NULL, 
    table_name VARCHAR(9) 
); 
INSERT INTO RatedTables (table_name) VALUES ('Problems','Solutions'); 
CREATE TABLE Ratings (
    id INT PRIMARY KEY NOT NULL, 
    rated_table_id TINYINT NOT NULL, 
    stars TINYINT, 
    FOREIGN KEY (rated_table_id) REFERENCES RatedTables(id) 
); 

但隨後我怎麼會讓它這樣,如果有相應的RatingSolution被刪除那麼這些評級會過於?????

+0

如何在等級表中添加另一列problem_id int使用外鍵約束FOREIGN KEY(problem_id)參考問題(id)ON DELETE CASCADE –

回答

0

你基本上有兩個選擇,但這是回顧和檢查你的數據庫結構的好機會。

的第一個選擇是做這樣的事情:

CREATE TABLE potential_link1 (
    id int primary key, 
    ... 
); 
CREATE TABLE potential_link2 (
    id int primary key, 
    .... 
); 
CREATE TABLE ratings (
    id int primary key, 
    potential_link1 int references potential_link1(id) on delete cascade, 
    potential_link2 int references potential_link2(id) on delete cascade, 
    .... 
    check(potential_link1 is null or potential_link2 is null), 
    check(potential_link2 is not null or potential_link1 is not null) 
); 

這工作,但你可以看到這是一個有點複雜。

第二種可能性是,由於有清楚的情況,其中a依賴於b和c的聯合,因此您可以考慮是否可以重構您的數據庫結構以反映出來,因此您只需要一張表來鏈接。

+1

在OP中,它們已經有一個FK引用,並帶有'on delete cascade' 'potential_link1'和'potential_link2'之間。所以我不認爲你可以在''cascade'上用''rating'創建這些外鍵(因爲SQL Server的過度週期檢測器) –

0

兩張表看起來非常相似沒有任何問題。它們包含的內容各不相同,例如無論是問題還是解決方案,您都不會選擇所有三星評級 - 您總是可以使用解決方案評級問題評級。


但有一個表都收視率一點也沒有錯,當你想收視率有同樣的表現,無論對問題或解決方案(例如,兩個人都要有1到5顆星可以是一個好主意,兩人都可以發表評論,不再有200個字符,......)。

這可以通過簡單地給表中的外鍵添加一個problem_id和一個solution_id的收視表來完成,並且總是填充一個或另一個。隨着自然鍵,同樣會感覺更加很好的,天然:

  • problem(problem_no, data)
  • solution(problem_no, solution_no, data)
  • rating(problem_no, solution_no, data)

與兩個父表rating.solution_no可空和外鍵。

相關問題