我想创建一个表"新闻"作为例子。在此表中,我有一个group_id
和一个lang_id
。 group_id
保留"新闻"的ID但是group_id
因为它在某些语言中有翻译。如果我插入新的"新闻" group_id
,autoIncrement
将为lang_id
使用不同的lang_id
但对于我附加到插入命令的每个group_id
都是相同的
例如,我希望实现的目标
我在这里说新的德语新闻(1),英语(2),法语(3)它将为这个Langs创建新的行,具有相同的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
如何使用主键实现这一点,lstValues.add(total.getString("uname")+","+total.getString("loginname")+","+total.getString("uadd"));
将成为主键?
答案 0 :(得分: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
答案 1 :(得分: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
Zohar Peled解释说,这三种方法会更好。这是一个没有匈牙利符号的版本:
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)
);