2016-12-22 4 views
0

Я хочу создать таблицу «Новости» в качестве примера. В этой таблице у меня есть group_id и lang_id. group_id остается в качестве идентификатора для «Новостей», но как group_id, потому что он имеет перевод на некоторых языках. Этот group_id должен быть autoIncrement, если я вставляю новую «Новости» с разными lang_id, но то же самое для каждого lang_id. Я прикрепляю к команде Insert.
Пример таблицы, которую я хочу достичь.
Я говорю здесь new Новости на немецком языке (1), английском (2), французском (3) он должен создавать новые строки для этого Langs с тем же group_id, но сам автоматически Increment.Первичный ключ, который существует несколько раз

Таблица: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», используя последовательность. Еще лучше сделайте это 2 таблицы, где group_id находится в «родительской» таблице. –

ответ

1

Первичный ключ должен быть уникальным по определению.
Это означает, что в вашем случае первичным ключом таблицы должна быть комбинация group_id и lang_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 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) 
);