C# 正确使用查找表和对NET的修改

C# 正确使用查找表和对NET的修改,c#,sql,sql-server,enums,C#,Sql,Sql Server,Enums,我需要创建一些查找表,我经常看到以下内容: create table Languages ( Id int identity not null primary key (Id), Code nvarchar (4) not null, Description nvarchar (120) not null, ); create table Posts ( Id int identity not null primary key (Id), Langu

我需要创建一些查找表,我经常看到以下内容:

create table Languages
(
  Id int identity not null primary key (Id),      
  Code nvarchar (4) not null,
  Description nvarchar (120) not null,
);

create table Posts
(
  Id int identity not null primary key (Id),      
  LanguageId int not null,
  Title nvarchar (400) not null,
);

insert into Languages (Id, Code, Description) values (1, "en", "English");
create table Languages
(
  Code nvarchar (4) not null primary key (Code),      
  Description nvarchar (120) not null,
);

create table Posts
(
  Id int identity not null primary key (Id),      
  LanguageCode nvarchar (4) not null,
  Title nvarchar (400) not null,
);

insert into Languages (Code, Description) values ("en", "English");
通过这种方式,我用语言id本地化帖子

IMHO,这不是语言表的最佳方案,因为在查找表中PK应该是有意义的,对吗

因此,我将使用以下方法:

create table Languages
(
  Id int identity not null primary key (Id),      
  Code nvarchar (4) not null,
  Description nvarchar (120) not null,
);

create table Posts
(
  Id int identity not null primary key (Id),      
  LanguageId int not null,
  Title nvarchar (400) not null,
);

insert into Languages (Id, Code, Description) values (1, "en", "English");
create table Languages
(
  Code nvarchar (4) not null primary key (Code),      
  Description nvarchar (120) not null,
);

create table Posts
(
  Id int identity not null primary key (Id),      
  LanguageCode nvarchar (4) not null,
  Title nvarchar (400) not null,
);

insert into Languages (Code, Description) values ("en", "English");
网络应用程序通常使用语言代码,这样我就可以不用连接就能获得一篇英语文章

通过这种方法,我还可以维护数据库数据的完整性

这可以应用于代码为“M”、“F”的性别表、国家表、交易类型表(我应该吗?…)

然而,我认为在查找表中使用int作为PK是很常见的,因为它更容易映射到枚举

并且知道甚至可以映射到标志枚举,以便在枚举中具有多对多关系

这在网络代码中很有帮助,但实际上有局限性。无法将语言表映射到标志枚举

。。。标志枚举不能有超过64项(Int64),因为键必须是2的幂

解决方案

我决定寻找一种加强数据库数据完整性的方法,并且仍然可以使用枚举,因此我尝试:

create table Languages
(
  Code nvarchar (4) not null primary key (Code),
  Key int not null,      
  Description nvarchar (120) not null,
);

create table Posts
(
  Id int identity not null primary key (Id),      
  LanguageCode nvarchar (4) not null,
  Title nvarchar (400) not null,
);

insert into Languages (Code, Key, Description) values ("en", 1, "English");
通过这种方法,我有了一个有意义的语言代码,我避免了连接,我可以通过解析键来创建枚举:

public enum LanguageEnum {
  [Code("en")
  English = 1
}
我甚至可以在属性中保留代码。或者我可以切换代码和描述

那么标志枚举呢?嗯,我将没有标志枚举,但我可以有列表

当使用列表时,我没有64项的限制

对我来说,所有这些都是有意义的,但我会将其应用于角色表还是ProductsCategory表

在我看来,我只适用于很少随时间变化的表格。。。因此:

Languages, Countries, Genders, ... Any other example?
关于以下内容,我不确定(它们是应用程序固有的):

对于这些,我不会申请(它们可以由CMS管理):


您认为我查找表的方法如何?

第一种方法是正确的,使用ID作为PK。(您还可以在“代码”列上设置唯一索引。)

“PK应该是有意义的,对吧?”

没有。这不是一项要求;在多年的DBMS工作中,我从未听说过它


请记住,大多数RDBMS都对int键进行了优化,查找和int PK的速度比大多数其他数据类型都快。这就是为什么这么多PK都使用标识的原因之一。

为什么要投票给close?我的问题出了什么问题?主要是因为不清楚你在问什么(主要是因为你显然是在自言自语,而不是用SO的问答形式问/回答你自己的问题)。希望有帮助。使用自然钥匙没有什么错。对于一种语言,我认为使用该语言的ANSI代码是语言表的完美主键。“en-us”非常清楚,其中1(标识值)不提供任何额外好处。当使用字符数据作为键出现性能问题时,值的宽度变化很大。@SeanLange:True,是的。然而,使用标识的意义在于,当某个东西更改了它的名称时,不需要进行任何更改。虽然像‘en-us’这样的语言代码或其他100种语言代码中的任何一种都很可能不会改变,但仍然有一个有限的机会(我现在正处于挑剔的角落!)我的主要观点是,没有要求查找表的PK必须是查找代码而不是Id。关于自然键和代理键的讨论(争论)一直在进行。与改变语言代码的值相比,地球明天被流星毁灭的可能性更大。我的观点是你说使用身份是正确的方法。很多时候,在一个查找表中,我会同意,但其他时候,这对我来说就是没有意义。状态表是否使用标识?如果是这样的话,给一个状态分配一个基本上是随机的数字有什么帮助?你有没有任何链接支持你的说法,即“大多数RDBMS对int键进行了优化,并且比大多数其他数据类型查找和int PK更快”?:)对于一个状态表,我确实使用随机int,是的!古怪,我知道,但它形成了一个一致的模式。。。我确实为我的优化声明寻找了链接,但我检查的链接大多是像我一样的一次性评论。甚至在代理键旁边有[需要引用],所以我可能需要对此做一些思考。活到老学到老!