为两列或更多列创建复合主键时,例如PRIMARY KEY(col1, col2, col3);系统将INDEX每列单独?
我问这个问题的原因是,当我们使用 时UNIQUE INDEX (col1, col2, col3),它INDEX仅作为第一列,我们需要INDEX为其他列创建额外的s。我想知道复合主键是否也是这种情况。
我正在构建一个 Web 应用程序(项目管理系统),并且在性能方面我一直对此感到疑惑。
我有一个问题表,里面有 12 个外键链接到各种其他表。其中,我需要加入其中的 8 个以从其他表中获取标题字段,以便记录在 Web 应用程序中有意义,但这意味着进行 8 个连接,这似乎非常多,尤其是因为我只是在拉入每个连接有 1 个字段。
现在我还被告知要使用自动递增的主键(除非分片是一个问题,在这种情况下我应该使用 GUID)出于永久性原因,但是使用 varchar(最大长度 32)性能有多糟糕?我的意思是这些表中的大多数可能不会有很多记录(其中大多数应该低于 20)。此外,如果我使用标题作为主键,我将不必在 95% 的时间内进行连接,因此对于 95% 的 sql,我什至会发生任何性能下降(我认为)。我能想到的唯一缺点是我的磁盘空间使用量会更高(但一天下来真的很重要)。
我使用查找表来代替枚举的原因是因为我需要最终用户通过应用程序本身来配置所有这些值。
使用 varchar 作为表的主键的缺点是什么,除非有很多记录?
更新 - 一些测试
所以我决定对这些东西做一些基本的测试。我有 100000 条记录,这些是基本查询:
基本 VARCHAR FK 查询
SELECT i.id, i.key, i.title, i.reporterUserUsername, i.assignedUserUsername, i.projectTitle,
i.ProjectComponentTitle, i.affectedProjectVersionTitle, i.originalFixedProjectVersionTitle,
i.fixedProjectVersionTitle, i.durationEstimate, i.storyPoints, i.dueDate,
i.issueSecurityLevelId, i.creatorUserUsername, i.createdTimestamp,
i.updatedTimestamp, i.issueTypeId, i.issueStatusId
FROM ProjectManagement.Issues i
Run Code Online (Sandbox Code Playgroud)
基础 INT FK 查询
SELECT i.id, i.key, i.title, ru.username as reporterUserUsername,
au.username as assignedUserUsername, p.title as projectTitle,
pc.title as …Run Code Online (Sandbox Code Playgroud) 我正在开发一个 SQL Server 2012 数据库,我对 nvarchar 列作为主键有疑问。
我有这张桌子:
CREATE TABLE [dbo].[CODES]
(
[ID_CODE] [bigint] IDENTITY(1,1) NOT NULL,
[CODE_LEVEL] [tinyint] NOT NULL,
[CODE] [nvarchar](20) NOT NULL,
[FLAG] [tinyint] NOT NULL,
[IS_TRANSMITTED] [bit] NOT NULL DEFAULT 0,
CONSTRAINT [PK_CODES] PRIMARY KEY CLUSTERED
(
[CODE_LEVEL] ASC,
[CODE] ASC
)
)
Run Code Online (Sandbox Code Playgroud)
但现在我想使用[CODE]列作为主键并删除[ID_CODE]列。
如果我有一个NVARCHAR专栏,有什么问题或惩罚PRIMARY KEY吗?
[CODE]列值必须是唯一的,所以我认为我可以UNIQUE为该列设置约束。
我是否必须用[CODE]作主键,还是UNIQUE在[CODE]列上设置约束更好?
我将传感器数据存储在表SensorValues 中。表和主键如下:
CREATE TABLE [dbo].[SensorValues](
[DeviceId] [int] NOT NULL,
[SensorId] [int] NOT NULL,
[SensorValue] [int] NOT NULL,
[Date] [int] NOT NULL,
CONSTRAINT [PK_SensorValues] PRIMARY KEY CLUSTERED
(
[DeviceId] ASC,
[SensorId] ASC,
[Date] DESC
) WITH (
FILLFACTOR=75,
DATA_COMPRESSION = PAGE,
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF,
ONLINE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON)
ON [MyPartitioningScheme]([Date])
Run Code Online (Sandbox Code Playgroud)
然而,当我选择在特定时间有效的传感器值时,执行计划告诉我它正在执行排序。这是为什么?
我原以为,由于我存储了按日期列排序的值,因此不会发生排序。还是因为索引不仅仅按日期列排序,即它不能假设结果集已排序?
SELECT TOP 1 SensorValue
FROM SensorValues
WHERE SensorId = 53
AND DeviceId = …Run Code Online (Sandbox Code Playgroud) 我知道这类问题经常出现,但我还没有读到任何有说服力的论据来帮助我做出这个决定。请多多包涵!
我有一个巨大的数据库 - 它每天增长大约 10,000,000 条记录。数据是相关的,出于性能原因,我使用 BULK COPY 加载表。出于这个原因,我需要为行生成键,并且不能依赖 IDENTITY 列。
一个 64 位整数 - bigint - 对我来说足够宽,但为了保证唯一性,我需要一个集中式生成器来为我制作 ID。我目前有这样一个生成器服务,它允许服务保留 X 序列号并保证没有冲突。但是,这样做的结果是,我拥有的所有服务都依赖于这个集中式生成器,因此我在分发系统方面受到限制,并且对强加的其他依赖项(例如需要网络访问)不满意通过这种设计。这有时是一个问题。
我现在正在考虑使用顺序 GUID 作为我的主键(在 SQL 外部生成)。据我自己的测试确定,这些唯一的缺点是更广泛的数据类型的磁盘空间开销(由于它们在索引中的使用而加剧)。与 bigint 替代方案相比,我没有目睹任何明显的查询性能下降。使用 BULK COPY 加载表稍慢,但不会慢很多。由于我的顺序 GUID 实现,我的基于 GUID 的索引不会变得碎片化。
基本上,我想知道的是是否还有其他我可能忽略的注意事项。目前,我倾向于采取飞跃并开始使用 GUID。我绝不是数据库专家,所以我真的很感激任何指导。
我有下表:
CREATE TABLE word(
word CHARACTER VARYING NOT NULL,
id BIGINT NOT NULL,
repeat INTEGER NOT NULL
);
ALTER TABLE public.word OWNER TO postgres;
ALTER TABLE ONLY word ADD CONSTRAINT "ID_PKEY" PRIMARY KEY (word,id);
Run Code Online (Sandbox Code Playgroud)
当我尝试使用以下命令恢复它时:
psql -U postgres -h localhost -d word -f word.sql
Run Code Online (Sandbox Code Playgroud)
它给了我这个错误:
不允许表“word”的多个主键
如何在 postgres 中使用多个主键?
我对数据库这个主题很陌生,所以这可能听起来很无知,但我很好奇为什么应该在表中明确显示一个键。这主要是为了告诉用户给定的列值(希望)保证在每一行中都是唯一的?即使没有提到它的独特性,它也应该仍然存在。
可以CURRENT_TIMESTAMP用作PRIMARY KEY?
是否有可能两个或多个不同的 INSERT 得到相同的结果CURRENT_TIMESTAMP?
在所有表中使用单个序列作为主键(而不是主键对于给定表是唯一的,它对于所有表都是唯一的)是否可以接受?如果是这样,客观上是否比跨表使用单个主键序列更好。
我是一名初级软件开发人员,而不是 DBA,所以我仍在学习良好数据库设计的许多基础知识。
编辑:如果有人想知道,我最近阅读了我们公司的一位 DBA 对数据库设计的评论,他提到设计没有在整个数据库中使用单个主键是一个问题,这听起来与到目前为止我已经学会了。
Edit2:要回答评论中的问题,这是针对 Oracle 11g 的,但我想知道非数据库特定级别。如果这个问题确实取决于数据库,我很想知道原因,但在这种情况下,我会寻找特定于 Oracle 的答案。
我有table1和table2在 MySQL 中。两者都有一个主auto_increment键id。
如果表模式匹配并且我对INSERT INTO table1 (SELECT * FROM table2)插入到的新行执行什么操作table1?id当一行 fromtable1相同时,它们是否保留旧值并产生冲突id?新值是否由 auto_increment 生成?它取决于存储引擎还是锁定?
primary-key ×10
mysql ×3
sql-server ×3
postgresql ×2
index ×1
innodb ×1
performance ×1
timestamp ×1