2016-12-22 18 views
0

我想創建一個表「News」作爲示例。在這個表中,我有一個group_id和一個lang_idgroup_id與「新聞」的ID保持一致,但保留爲group_id,因爲它在某些語言中有翻譯。這個group_id應該是autoIncrement如果我插入一個新的「新聞」與不同的lang_id但我附加到插入命令每個lang_id相同。
例如,我想要實現的表格。
我在這裏說新的德語(1),英語(2),法語(3)的新聞,它應該爲這個Langs創建新的行,與group_id相同,但它本身自動增量。存在多次的主鍵

表:News

x-----------------------------x 
| group_id| lang_id | news | 
x---------|-----------|-------x    
| 1 |  1  | Hallo | 
| 1 |  2  | Hello | 
| 1 |  3  | Holla | 
| 2 |  1  | bye | 
| 2 |  2  | byebye| 
| 2 |  3  | Ciao | 
x-----------------------------x 

我怎麼能做到這一點與主鍵,group_id將是主鍵?

+3

你不能,因爲它不是唯一的。主鍵必須是唯一的。您應該使用groupid和lang_id創建一個密鑰。主鍵意味着如果你要求一個具有特定鍵的行,你只能返回一行。 –

+0

PS你不能將'group_id'設置爲自動增量,因爲每行都會得到一個*不同的*值。 –

+1

group_id,lang_id組合將形成主鍵,您可以通過使用序列使group_id成爲「auto inc」值。更好的是,在group_id位於「父」表中的情況下,創建2個表。 –

回答

1

根據定義,主鍵必須是唯一的。
這意味着在你的情況下,表的主鍵應該是group_idlang_id的組合。
至於如果你的group_id可以是一個標識列的問題,這是可能的,但你將不得不爲現有內容的每種新語言使用SET IDENTITY_INSERT

例如:

CREATE TABLE tblNews 
(
    group_id int identity(1,1) not null, 
    lang_id int not null, 
    news varchar(20), 
    primary key(group_id, lang_id) 
) 

INSERT INTO tblNews VALUES(1, 'hello') 

SET IDENTITY_INSERT tblNews ON 
INSERT INTO tblNews (group_id, lang_id, news) VALUES(1, 2, 'hello') 
INSERT INTO tblNews (group_id, lang_id, news) VALUES(1, 3, 'holla') 
SET IDENTITY_INSERT tblNews OFF 

INSERT INTO tblNews VALUES(1, 'good bye') 

SET IDENTITY_INSERT tblNews ON 
INSERT INTO tblNews (group_id, lang_id, news) VALUES(2, 2, 'byebye') 
INSERT INTO tblNews (group_id, lang_id, news) VALUES(2, 3, 'Ciao') 
SET IDENTITY_INSERT tblNews OFF 

SELECT * 
FROM tblNews 

結果:

group_id lang_id  news 
1   1   hello 
1   2   hello 
1   3   holla 
2   1   good bye 
2   2   byebye 
2   3   Ciao 

雖然這樣的設計顯然是可能的,我有一個很難推薦它。我可能會使用多語言的數據庫不同的方法 - 在新聞一個表,對於語言之一表,一個表的翻譯:

tblNews 
newsId int identity(1,1) primary key, 
-- and whatever else content that is not language-dependent 

tblLanguages 
languageId int identity(1,1), 
languageName nvarchar 

tblNewsContent 
NewsId (pk) 
LanguageId (pk) 
Contant nvarchar 
+0

我會將其標記爲正確答案,以作爲此類問題的最佳解決方案。因爲它是最佳實踐,所以我將使用3表格模式。 – AkAk47

+0

很高興幫助:-)。我不知道這是否是最佳做法,但它是我所知道的最好的做法:-)。 –

0

三分表法是最好的選擇,但我會說它需要一些獨特的,不依賴於翻譯的東西。

如果你在SQL Server 2012+上,你可以使用這種情況的順序,但我不能說這是最佳實踐。

rextester:http://rextester.com/RRTJ4439

create sequence dbo.NewsIdSequence as int start with 1 increment by 1; 

create table Lang (
    id int not null 
    , name nvarchar(64) 
    , alias nvarchar(64) 
    , constraint pk_Lang primary key clustered (id) 
    , constraint uq_Lang_Name unique (name) 
); 

create table NewsLanguage (
    news_id int not null 
    constraint df_NewsLanguage_news_id default (next value for dbo.NewsIdSequence) 
    , lang_id int not null 
    , title nvarchar(256) not null 
    , article nvarchar(max) not null 
    , constraint pk_NewsLanguage primary key clustered (news_id, lang_id) 
    , constraint fk_langLanguage_lang_id foreign key (lang_id) references lang(id) 
); 

insert into Lang (id, Name, alias) 
    select top 3 langid, name, alias 
    from syslanguages 
    order by langid; 

declare @NextNewsId int; 
set @NextNewsId = next value for dbo.NewsIdSequence; 

insert into NewsLanguage(news_id, lang_id, title, article) 
      select @NextNewsId, 0, 'Hello', 'Hello ... ' 
    union all select @NextNewsId, 1, 'Hallo', 'Hallo ... ' 
    union all select @NextNewsId, 2, 'Bonjour', 'Bonjour ...'; 

set @NextNewsId = next value for dbo.NewsIdSequence; 

insert into NewsLanguage(news_id, lang_id, title, article) values 
    (@NextNewsId, 0, 'Goodbye','Goodbye ...') 
    , (@NextNewsId, 1, 'Auf Wiedersehen', 'Auf Wiedersehen ...') 
    , (@NextNewsId, 2, 'Au Revoir', 'Au Revoir ...'); 

select * 
    from dbo.NewsLanguage nl 
    inner join dbo.Lang l on nl.lang_id = l.id 

三分表法效果會更好,因爲瑣佩萊德解釋。這裏是一個沒有匈牙利符號的版本:

create table Lang (
    id int not null identity (1,1) 
    , name nvarchar(64) 
    , alias nvarchar(64) 
    , constraint pk_Lang primary key clustered (id) 
    , constraint uq_Lang_Name unique (name) 
); 

create table News (
    id int not null identity (1,1) 
    , unique_column_of_importance nvarchar(64) 
    , constraint pk_News primary key clustered (id) 
    , constraint uq_News_Title unique (unique_column_of_importance) 
); 

create table NewsLanguage (
    news_id int not null 
    , lang_id int not null 
    , title nvarchar(256) not null 
    , article nvarchar(max) not null 
    , constraint pk_NewsLanguage primary key clustered (news_id, lang_id) 
    , constraint fk_NewsLanguage_news_id foreign key (news_id) references news(id) 
    , constraint fk_NewsLanguage_lang_id foreign key (lang_id) references lang(id) 
);