Eu tenho duas tabelas do SQL Server 2014, uma com nomes e descrições de cultura "en-GB" e uma segunda com traduções para outras culturas.
A tabela "en-GB"...
CREATE TABLE [dbo].[HomePages]
(
[Id] INT IDENTITY (1, 1) NOT NULL,
[Key] NVARCHAR (25) NOT NULL,
[Name] NVARCHAR (100) NOT NULL,
[Description] NVARCHAR (256) NOT NULL,
[Active] BIT CONSTRAINT [DF_HomePages_Active] DEFAULT ((0)) NOT NULL,
CONSTRAINT [PK.dbo.HomePage] PRIMARY KEY CLUSTERED ([Id] ASC)
);
A tabela de tradução:
CREATE TABLE [dbo].[HomePageTranslations]
(
[Id] INT IDENTITY (1, 1) NOT NULL,
[HomePageId] INT NOT NULL,
[CultureName] NVARCHAR (5) NOT NULL,
[Name] NVARCHAR (100) NOT NULL,
[Description] NVARCHAR (256) NOT NULL,
CONSTRAINT [PK_HomePageTranslations] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_HomePageTranslations_Globalization] FOREIGN KEY ([CultureName]) REFERENCES [dbo].[Globalization] ([CultureName]) ON DELETE CASCADE,
CONSTRAINT [FK_HomePageTranslations_HomePages] FOREIGN KEY ([HomePageId]) REFERENCES [dbo].[HomePages] ([Id]) ON DELETE CASCADE
);
Sempre haverá valores na tabela en-GB, mas podem ou não ser valores equivalentes na tabela de conversão. A consulta que estou usando deve retornar os valores traduzidos, se existirem, ou recorrer aos valores en-GB, se não existirem. A consulta está no procedimento armazenado aqui:
CREATE PROCEDURE [dbo].[HomePage_GetForKeyAndCulture]
(
@Key NVARCHAR(25),
@CultureName NVARCHAR(5)
)
AS
BEGIN
SELECT [base].[Id],
[base].[Key],
COALESCE(translation.[Name], base.[Name]) [Name],
COALESCE(translation.[Description], base.[Description]) [Description],
[base].[Active]
FROM [dbo].[HomePages] [base]
LEFT JOIN [dbo].[HomePageTranslations] [translation]
ON [translation].[HomePageId] = [base].[Id]
AND [translation].[CultureName] = @CultureName
WHERE [Key] = @Key;
END
Como você pode ver, estou usando LEFT JOIN e a função COALESCE para conseguir isso. Eu sei que LEFT JOINS não são muito eficientes, então existe uma maneira mais eficaz de conseguir isso?
EDIT: As tabelas de aviso a seguir agora tiveram índices adicionados e se parecem com ...
A tabela PÁGINA INICIAL...
CREATE TABLE [dbo].[HomePages]
(
[Id] INT IDENTITY (1, 1) NOT NULL,
[Key] NVARCHAR (25) NOT NULL,
[Name] NVARCHAR (100) NOT NULL,
[Description] NVARCHAR (256) NOT NULL,
[Active] BIT CONSTRAINT [DF_HomePages_Active] DEFAULT ((0)) NOT NULL,
CONSTRAINT [PK.dbo.HomePages] PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE UNIQUE NONCLUSTERED INDEX [IX.HomePages_Key]
ON [dbo].[HomePages]([Key] ASC);
E a tabela TRADUÇÃO...
CREATE TABLE [dbo].[HomePageTranslations]
(
[Id] INT IDENTITY (1, 1) NOT NULL,
[HomePageId] INT NOT NULL,
[CultureName] NVARCHAR (5) NOT NULL,
[Name] NVARCHAR (100) NOT NULL,
[Description] NVARCHAR (256) NOT NULL,
CONSTRAINT [PK_HomePageTranslations] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_HomePageTranslations_Globalization] FOREIGN KEY ([CultureName]) REFERENCES [dbo].[Globalization] ([CultureName]) ON DELETE CASCADE,
CONSTRAINT [FK_HomePageTranslations_HomePages] FOREIGN KEY ([HomePageId]) REFERENCES [dbo].[HomePages] ([Id]) ON DELETE CASCADE
);
CREATE UNIQUE NONCLUSTERED INDEX [IX_HomePageTranslations_HomePageIdCultureName]
ON [dbo].[HomePageTranslations]([HomePageId] ASC, [CultureName] ASC);
ninguém se preocupou com uma resposta
um índice em [HomePages] [Key]
um índice em [HomePageTranslations] [CultureName], [HomePageId]
e torná-lo uma restrição exclusiva, se apropriado
a consulta em si parece boa para mim
você provavelmente poderia apenas usar uma exibição e um índice em [HomePageTranslations] [HomePageId] e ter uma resposta fina
10s de milhares não é muito