我正在开发一个 PHP 多语言网站,如果可用,我想获取给定语言的内容,如果不可用,则希望获取另一种语言的内容。我将在下面尝试解释我的问题。如果有什么不清楚的地方,请告诉我。
content : content_id, url, datecontent_l10n : content_id, l10n_id, title, descriptionl10n : l10n_id, name, order→ 使用 JOIN 很容易实现。
→ 如何实现?是否可以在单个请求中实现?
content 行(例如,对于标题列表)。title 已翻译,但description 为NULL。理想情况下,请求会选择给定语言的标题,但会回退到另一种语言的描述。 l10n 的语言,按 order ASC 排序)。非常感谢您的帮助!提前谢谢你!
亲切的问候,
奥利维耶
最佳答案
此解决方案适用于许多行,但每种语言需要 1 个 LEFT JOIN,并且 JOIn 的顺序指定优先级。
SELECT c.url, c.date,
COALESCE( c1.title, c2.title ),
COALESCE( c1.description, c2.description )
FROM content c
LEFT JOIN content_l10n c1 ON (c1.content_id = c.content_id AND c1.l10n_id=$1)
LEFT JOIN content_l10n c2 ON (c2.content_id = c.content_id AND c2.l10n_id=$2)
(注意:我在这里假设 $1 和 $2 是用户的前 2 种首选语言,它们缓存在 session 中,因此不需要额外的 l10n JOIN)。
对于您的表结构,这是设置语言顺序的唯一有意义的方法。您将需要一个额外的表来指定每个用户的语言首选项,而不是将顺序存储在 l10n 表中。假设你有一张 table
user_l10n( user_id, l10n_id, order )
让我们假设表 l10n 保留其“order”字段作为默认值。
如果你这样做:
SELECT ..., COALESCE(ul.order,l.order) AS order
FROM
content c
JOIN content_l10n cl USING (content_id)
JOIN l10n l USING (l10n_id) -- get default language order
LEFT JOIN user_l10n ul ON (ul.l10n_id=l.l10n_id -- get user preferences if available
AND ul.user_id=$user_id)
WHERE search condition on content, etc
ORDER BY content_id, COALESCE(ul.order,l.order)
您将获得所有匹配的文档,以及用户指定的(或默认的)排序,因此应用程序可以轻松地对此进行排序。
现在的想法是避免从数据库中检索所有行,这些行的语言被用户喜欢的语言的现有翻译“遮蔽”。
执行此操作的自然方法是 GROUP BY,但 MySQL 没有适用于此处的聚合函数...
你可以做一个依赖子查询(用于标题和描述);抓取一行没问题,但如果您想抓取多行,速度会非常慢。
但是你也可以做点别的!这依赖于 MySQL 的非标准 GROUP BY 子句的一些可疑行为......
首先,收集您要显示的“content_id”列表(分页搜索查询的结果,无论如何)。然后你可以做类似下面恐怖的事情:
SELECT * FROM
(
SELECT content_id, title FROM
(
SELECT c.content_id, c.title
FROM
content c
JOIN content_l10n cl USING (content_id)
JOIN l10n l USING (l10n_id)
LEFT JOIN user_l10n ul ON (ul.l10n_id=l.l10n_id AND ul.user_id=$user_id)
WHERE cl.content_id IN ($list) AND c.title IS NOT NULL
ORDER BY content_id, COALESCE(ul.order,l.order)
) d GROUP BY content_id
) t
JOIN
(
SELECT content_id, description FROM
(
SELECT c.content_id, c.description
FROM
content c
JOIN content_l10n cl USING (content_id)
JOIN l10n l USING (l10n_id)
LEFT JOIN user_l10n ul ON (ul.l10n_id=l.l10n_id AND ul.user_id=$user_id)
WHERE cl.content_id IN ($list) AND c.description IS NOT NULL
ORDER BY content_id, COALESCE(ul.order,l.order)
) d GROUP BY content_id
)
USING (content_id)
关于php - 多语言 MySQL 内容 : how to select a given language or another if the one specified isn't available?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5919733/