嗯,我对数据库架构知之甚少,但我真的不明白CTO的想法,但他坚持用字符作为 我们使用的所有表的主键的列类型。 但主键仍然如下所示 - > 1,2,3 ...等等。它们是数字的。 所以我使用integer + auto_increment进行合成PK
但CTO表示,他不能在PK上使用LIKE
条件发出查询,这很糟糕?!
PS - 所以不是自动递增/触发,序列CTO发出选择查询提取 表中最大的值,他加1,然后他将该值转换为字符串 然后存储它。
编辑
谢谢您的帮助 !但我需要说服他,这将是一场灾难。
我只是被告知这个(在这种情况下的角色4 PK)是一个坏主意。
他的论点是......
1.角色PK不会占用太多空间。
2.如果使用int类型PK,数据库查询优化器必须重新读取您的查询
因为你必须发出类似的东西
"select * from employee where name like 'somename'
和
Select * from employee where id = 6
。
因为where子句改变了。
他强烈主张我们使用的东西就像是
"select * from employee where @columnName like @value"
他这样说,查询优化器会运行得更好。
我如何证明或给他一些改变主意的正当理由?
谢谢:)
答案 0 :(得分:4)
你的首席技术官犯这个决定错误的原因很多;我先谈谈几点:
正如您所指出的,您必须采取额外步骤来生成新的自动递增PRIMARY KEY。这是一项计算成本,也增加了未来某些时候不一致应用的可能性。
一旦超过4个字符,字符将在磁盘空间中花费更多(换句话说,12345比“12345”便宜得多)。
如果您在主键上使用聚簇索引(这是某些RDBM的默认设置),则对字符进行排序与排序整数完全不同:
人物:1,10,101,11,12,13,14,15 ...... 数字:1,2,3,4 ......
如果您将最大数值作为字符插入,则会破坏索引。这不是一个不可逾越的问题,但更多的是浪费了计算能力来清理。
至于你关于在PRiMARY KEY上使用LIKE的第二个问题,我想不出你为什么会这样做的原因;如果您需要LIKE的强大功能,通常是因为您为用作PRIMARY KEY的列分配了某种重要性,这意味着您需要将其公开给最终用户。如果是这种情况,那么我将使用代理自动递增数字主键,并向用户公开某种形式的ID。
答案 1 :(得分:1)
1:是的,没关系。也可以在汽车里每小时行驶10英里。汽车不会坏掉。在任何比较中,字符(或varchars)都是低速,因此结果是需要相同性能的更大预算。他们浪费空间,他们很慢。我建议你在这里做唯一明智的事 - 找一个不是白痴的人找工作。
2:甚至不确定。看,这里的问题是 - 这很可能只是你不能使用的东西。如:数据库不允许它。我真的没有尝试过 - 我也不会尝试以每小时100英里的速度撞击一个混凝土块,看它是否会损坏汽车。这没什么意义。
您的首席技术官显然需要休假并阅读一本书。可能有人应该与首席执行官谈谈并将他送到这里 - 他有一个白痴进入CTO职位。
有反对和合成(一个字段)主键的论据,但我从未在25年内与数据库合作,看到有人在DBase或Cobol之外做了。这是一个史诗般的无知。 Pointy Haired老板。
答案 2 :(得分:1)
好吧,你可以做这样的事情(假设SQL 2008 R2 +):
create table dbo.keep_the_peace (
pk as right(replicate('0',10)+convert(varchar(10),pk_generator),10) persisted not null
, pk_generator int not null identity(1,1)
, name nvarchar(128) not null
, constraint pk_keep_the_peace primary key nonclustered (pk)
, constraint uc_keep_the_peace unique clustered (pk_generator)
)
go
insert dbo.keep_the_peace (name) values ('Hello')
insert dbo.keep_the_peace (name) values ('World')
select * from dbo.keep_the_peace
优点:
pk
是varchar,CTO可以使用LIKE
pk
是自动生成的,无需重新查询插入pk
按正确的顺序排序。pk_generator
可用于外键约束,每个引用可节省6个字节,而CTO仍可加入pk
并获得正确的结果。keep_the_peace
上的非聚集索引将享有一个瘦小的聚类键(pk_generator
)缺点:
pk
+ pk_generator
每行使用14个字节,超过必要的10个字节。pk_keep_the_peace
每行使用14个字节,比必要的多14个字节。 (LOL)修改强>
他强烈主张我们使用的是“select * from” 员工@columnName喜欢@value“他这样说,查询 优化者会跑得更好。
如果WHERE
子句中的列发生更改,则会重新编译您的查询。没有办法避免这种情况。列可能以不同方式编制索引。
例如,对于id
上的聚簇索引,这将作为聚簇索引执行:
select * from employee where id = 6
然而这需要昂贵的表扫描:
select * from employee where name like 'somename%'
在name
上放置一个非聚集索引,对于同一个查询,您可以获得更高效的索引搜索+书签查找(通常)。
INT与CHAR无关。没有。字符键只占用较大的空间(通常),占用空间大,可降低I / O吞吐量。但是这些vanilla查询的性能在很大程度上取决于索引而不是数据类型。