Boa noite FernandoGuedes,
Primeiramente, este é meu primeiro post, se eu não for muito claro, me desculpe.
Eu estou implementando este tipo de funcionalidade da seguinte forma no banco de dados (MySQL).
Inicialmente eu possuo uma tabela de Idioma com as colunas ID, código da linguagem (en-us, pt-br, etc) e o nome da tabela de cada idioma.
Criando tabela de idiomas:
CREATE TABLE `languagem` (
`id` TINYINT(3) UNSIGNED NOT NULL AUTO_INCREMENT,
`langCode` VARCHAR(5) NOT NULL COLLATE 'utf8_bin',
`nomeTabela` VARCHAR(50) NOT NULL COMMENT 'Nome da tabela que armazena conteudo em determinado idioma.' COLLATE 'utf8_bin',
PRIMARY KEY (`id`)
)
COLLATE='utf8_bin'
ENGINE=InnoDB
AUTO_INCREMENT=1;
A estrutura das tabelas que armazenam os conteúdos em diferentes idiomas ficam assim:
Inicialmente eu possuo uma tabela com contém o ID do conteúdo e o ID de quem criou o conteúdo, pois dessa forma eu posso utilizar como chave estrangeira, já que o conteúdo é o mesmo, a única diferença é o idioma.
Criando tabela principal de textos para controlar os Ids:
CREATE TABLE `textos` (
`idTexto` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT ,
`idCriador` INT(11) UNSIGNED NOT NULL,
PRIMARY KEY (`idTexto`))
COMMENT='Armazena codigo unico de cada texto.'
COLLATE='utf8_bin'
ENGINE=InnoDB
AUTO_INCREMENT=1;
Agora eu posso criar uma tabela para o conteúdo em português, por exemplo. Essa estrutura de tabela se repete para cada idioma que você precisar.
Observe que a chave estrangeira permite que eu adicione o texto aqui apenas se o código já existe na tabela “texto” e caso eu delete um ID na tabela “textos” o conteúdo também será excluído nas tabelas de todos os idiomas.
Criando tabela de textos em português:
CREATE TABLE `texto_ptbr` (
`idTexto` INT(11) UNSIGNED NOT NULL,
`texto` TEXT NOT NULL COLLATE 'utf8_bin'
PRIMARY KEY (`idTexto`),
CONSTRAINT `FK_idTexto_ptbr` FOREIGN KEY (`idTexto`) REFERENCES `textos` (`idTexto`) ON UPDATE NO ACTION ON DELETE CASCADE
)
COMMENT='Sentences in english US'
COLLATE='utf8_bin'
ENGINE=InnoDB;
Agora, como eu uso tudo isso?
Com um procedure! Primeiro ele insere na tabela principal de “textos” para termos o Id único, depois seleciona o nome da tabela com base no ID do idioma que foi passado na chamada do procedure, e com o nome da tabela eu posso inserir o texto na tabela de português.
Criando procedimento para inserir texto no idioma desejado:
DELIMITER $$
CREATE PROCEDURE insere_texto (idCriador int, textoParaInserir TEXT, langId INT)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
BEGIN
ROLLBACK;
GET DIAGNOSTICS CONDITION 1 @errorCode = RETURNED_SQLSTATE, @errorMessage = MESSAGE_TEXT;
SELECT @errorCode, @errorMessage;
END;
START TRANSACTION;
INSERT INTO textos (textos.idCriador) VALUES (idCriador);
SELECT languagem.nomeTabela INTO @nomeTabelaSelecionada FROM languagem WHERE languagem.id = langId;
SET @insertTextQuery = CONCAT('INSERT INTO ', @nomeTabelaSelecionada, '(idTexto, texto)
VALUES (', LAST_INSERT_ID(), ', "', textoParaInserir, '")');
PREPARE insertTextStmt FROM @insertTextQuery;
EXECUTE insertTextStmt;
DEALLOCATE PREPARE insertTextStmt;
SELECT LAST_INSERT_ID() AS result;
COMMIT;
END
DELIMITER ;
Ah! Toda esse trabalho fica no banco, no PHP eu tenho apenas que chamar o procedure assim:
$query = “CALL insere_texto ($idCriador, $texto, $langId);”;
Obs.: Para simplificar, a chamada acima não utiliza prepared statement, recomento que utilize.