我正在构建一个 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) 我所说的一切都与关系数据库,特定的 MySQL 相关。
我在一个数据库中有许多表,对于其中一些,我想要在记录值更改时存储记录值的历史记录。我已经看到这以几种不同的方式完成:
这些不同的记录历史存储方法有哪些优缺点?还有其他我没有想到的方法吗?
我尝试使用 varchar 外键与 int 外键进行一些性能测试,并想知道外键约束如何影响 MySQL 的性能。
我认为它们会在一定程度上影响插入/更新,但是我在测试中不担心这一点。我想知道它们是否会影响 SELECT 语句以及它们是否会影响数据/索引大小?
所以我有一张有很多外键的表,但是当我要记录时,我需要加入这些表上的所有内容,因为我通常需要这些字段才能使记录有意义。基本查询如下所示:
SELECT i.id, i.`key`, i.title, i.description,
CONCAT(ru.firstName, ' ', ru.lastName) as `name`,
CONCAT(au.firstName, ' ', au.lastName) as `name`,
p.title, pc.title, pva.title, pvo.title, pvf.title, i.durationEstimate,
i.storyPoints, i.dueDate, isl.title, i.rejectionCount,
CONCAT(uc.firstName, ' ', uc.lastName) as `name`,
i.createdTimestamp, i.updatedTimestamp, it.title, isss.title
FROM ProjectManagement2.Issues i
INNER JOIN Users ru ON ru.id = i.reporterUserUsername
INNER JOIN Users au ON au.id = i.assignedUserUsername
INNER JOIN Projects p ON p.id = i.projectTitle
INNER JOIN ProjectComponents pc ON pc.id = i.projectComponentTitle
INNER JOIN ProjectVersions pva ON pva.id = …Run Code Online (Sandbox Code Playgroud)