Sql server 重复数据还是性能更好?

Sql server 重复数据还是性能更好?,sql-server,database-design,Sql Server,Database Design,我们需要用不同的语言显示我们的产品名称,但只有一些产品名称的语言和英语不同。当我们使用特定语言查询产品时,如果缺少特定语言名称,我们希望以英语显示默认名称 为了获得更好的查询性能,当缺少特定语言的名称时,我们必须将默认的英文名称填入依赖于语言的产品名称表(languageid+productid是主键)。它在这个依赖于语言的表中产生了大量重复的名称,当默认的英文名称更改时,更新这个表有点困难 目前,我们有大约300000个产品,约30种语言,此表中有超过8000000行,至少90%以上的数据是重

我们需要用不同的语言显示我们的产品名称,但只有一些产品名称的语言和英语不同。当我们使用特定语言查询产品时,如果缺少特定语言名称,我们希望以英语显示默认名称

为了获得更好的查询性能,当缺少特定语言的名称时,我们必须将默认的英文名称填入依赖于语言的产品名称表(languageid+productid是主键)。它在这个依赖于语言的表中产生了大量重复的名称,当默认的英文名称更改时,更新这个表有点困难

目前,我们有大约300000个产品,约30种语言,此表中有超过8000000行,至少90%以上的数据是重复的,并使用默认的英文名称填充。但是如果我们在查询中使用leftjoin和isnull检查,查询性能会慢得多

谁能向我推荐一种更好的数据库设计,以避免重复数据的填充,并具有更好的查询性能

当前表架构如下所示

Table1 (about 300,000 rows)
ProductId   | Country        | Currency  | others fields
------------|----------------|-----------|---------------
Product A   | US             | USD       | ...
Product B   | GB             | GBP       | ...

Table2 (about 9,000,000 rows)
LanguageId  | ProductId      | Product Name
------------|----------------|--------------------------
English     | Product A      | Product A Name
English     | Product B      | Product B Name
German      | Product A      | Produkt A Name
German      | Product B      | Product B Name (it's filled by English name)
我曾尝试在下面的查询中避免重复数据,但性能有点差

SELECT
    A.ProductId,
    A.Country,
    ISNULL(B1.ProductName, B2.ProductName) as ProductName
FROM
    Table1 A (NOLOCK)
    LEFT JOIN Table2 B1 (NOLOCK) on A.ProductId = B1.ProductId
    LEFT JOIN Table2 B2 (NOLOCK) on A.ProductId = B2.ProductId and B2.LanguageId = 'ENGLISH'
WHERE
    B1.LanguageId = 'German'
ORDER BY
    ISNULL(B1.ProductName, B2.ProductName)

我不确定这对于您的特定情况是否可行,但为什么不让UI接口层或应用程序层通过通用本地化模式处理翻译呢?

我不确定这对于您的特定情况是否可行,但是为什么不让UI界面层或应用程序层通过通用本地化模式处理翻译呢?

如果该语言记录中没有产品名称,请在该字段中输入一个
NULL
。执行查询时,请使用
COALESCE
NULL
替换为您的英文产品名称

SELECT COALESCE(l.ProductName, 'Product Name')
FROM Language l
我提议的设计如下:

Language | ProductName | TitleMenu
----------------------------------
English  | Widgetizer  | Title
French   | La Widgette | La Title
Spanish  |             | El Title

由于西班牙语有一个
NULL
条目,因此
COALESCE
跳过NULL并输入默认产品名称。

如果该语言记录中没有产品名称,请在该字段中输入
NULL
。执行查询时,请使用
COALESCE
NULL
替换为您的英文产品名称

SELECT COALESCE(l.ProductName, 'Product Name')
FROM Language l
我提议的设计如下:

Language | ProductName | TitleMenu
----------------------------------
English  | Widgetizer  | Title
French   | La Widgette | La Title
Spanish  |             | El Title

由于西班牙语有一个
NULL
条目,因此
COALESCE
跳过NULL并输入默认产品名称。

您测试过左连接和ISNULL了吗?还是这只是猜测?考虑到您正在转换大量数据,我想说可选语言行会快得多,除非您有一些非常糟糕的索引

SELECT COALESCE(l.ProductName, 'Product Name')
FROM Language l
SELECT
   ...,
   ISNULL(L.languageproductName, P.productname)
FROM
   Product P
   LEFT JOIN
   LangaugeStuff L ON P.productID = L.productID AND L.languageID = @Mylanguage

你测试过左连接和ISNULL了吗?还是这只是猜测?考虑到您正在转换大量数据,我想说可选语言行会快得多,除非您有一些非常糟糕的索引

SELECT
   ...,
   ISNULL(L.languageproductName, P.productname)
FROM
   Product P
   LEFT JOIN
   LangaugeStuff L ON P.productID = L.productID AND L.languageID = @Mylanguage

你能把当前的表模式放在你的帖子里吗?你能把当前的表模式放在你的帖子里吗?所以你建议了两列并保留了重复的英文名称?所以你建议了两列并保留了重复的英文名称?我在我的查询中尝试了左连接和ISNULL。因为我们还需要按产品名称对数据进行排序。速度要慢得多。我在查询中尝试了左连接和ISNULL。因为我们还需要按产品名称对数据进行排序。速度要慢得多。在UI层进行本地化很困难,因为我们还需要按产品名称字段进行排序。@CodeRhino,值得关注的问题。但是,在应用层中仍然可能进行本地化?当我只想在页面中显示指定的产品时,在应用层中处理本地化很容易。但是,当我想搜索和分页超过300000个产品并按产品名称显示结果和排序时,该如何处理呢?在UI层进行本地化很难,因为我们还需要按产品名称字段排序。@CodeRhino,值得关注的问题。但是,在应用层中仍然可能进行本地化?当我只想在页面中显示指定的产品时,在应用层中处理本地化很容易。但是,当我想搜索和分页超过300000个产品并显示结果和按产品名称排序时,我应该如何处理呢。