我正在开发一个多语言网站 PHP,如果可用,希望获取给定语言的内容,如果没有,则获取另一种语言的内容。我将尝试在下面解释我的问题。如果有什么不清楚的,请告诉我。

我的表:

  • content : content_id , url , date
  • content_l10n : content_id , l10n_id , title , description
  • l10n : l10n_id , name , order

  • 第一种情况:
  • 我的访客说法语。
  • 我要显示的内容有英文和法文两种版本。
  • 网站应显示法语内容。

  • → 使用 JOIN 易于实现。

    第二种情况:
  • 我的访客说法语。
  • 我要显示的内容是 只提供英文
  • 网站应显示英文内容。

  • → 如何实现?是否可以在单个请求中?

    一些注意事项:
  • 这必须可以扩展到两种以上的语言。
  • 解决方案必须适用于任何一种情况,因为在执行请求之前,我不知道内容是否以正确的语言提供。
  • 越快越好。
  • 如果需要,可以更改表。
  • 我想选择多个 content 行(例如,对于标题列表)。
  • 有时, title 被翻译,但 descriptionNULL 。理想情况下,请求会选择给定语言的标题,但会回退到另一种语言的描述。
  • 设置回退的顺序会很棒(首先:给定语言,然后: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 保留其“订单”字段作为默认值。

    如果你这样做:
    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/

    10-13 23:11