给定以下 SQL 表(例如 MySQL):
CREATE TABLE `table` (
`id` int(11) unsigned NOT NULL,
`lang` tinyint(3) unsigned NOT NULL,
`data` text NOT NULL,
PRIMARY KEY (`id`,`lang`)
) ENGINE=InnoDB
该表存储了一些关于具有 ID 的对象的数据,id
并且data
可以用多种语言编写 = lang
。此表的典型用例是:我们需要获取具有某个id的某个对象的数据,其中语言为lang = 1 或至少lang = 5 或任何其他语言,如果没有lang = 1 或 5 for id = 1 的行是成立。
换句话说,我想在英语或至少在德语上获得关于 id = 1 的对象的信息,但如果没有 - 任何其他语言就足够了。
这是一个相当简单的查询:
SELECT * FROM `table` WHERE `id` = 1
ORDER BY
CASE WHEN `lang` = 1 THEN 1
WHEN `lang` = 2 THEN 2
ELSE 3
END ASC
LIMIT 1
此查询非常快,并且仅使用 PRIMARY 键和内存排序。
当我们想通过一个查询获取多个对象的此类数据时,就会出现这些问题。我能想到的唯一一个是这样的:
SELECT id, (SUBQUERY TO GET DATA AS ABOVE WHERE id = tmp.id LIMIT 1) AS data
FROM (SUBQUERY TO SELECT ids) as tmp
该查询将完成它的工作,但它看起来和感觉都很丑:/
这是第一个问题: 做这些事情是一种好的和正确的方法吗?有人知道解决此类问题的更好方法吗?
现在让我们考虑一下高负载和非常大的数据表。例如,假设我们给了 1,000,000 个对象,每个对象有 5 到 15 种语言。对于 MySQL 来说,这确实是一个巨大的表,因此我们将一张表拆分为多个表(比如跨多个服务器的 20 个表)。现在我们有一些简单的哈希函数(比如 id % N == 0)来知道特定对象的数据存储在哪里。
所以,问题#2:*如果我们已经知道数据在哪里,如何跨多个表(即使在一个数据库中,从 table_1 到 table_5)发出这样的请求?* 我想这个问题只能在第一个之后才能回答:(
关于这个话题的其他几个问题:也许整个情况都是错误的?我们应该以其他方式存储这些数据吗?或者也许还有其他更有效的方法来做到这一点?