Pergunta

Digamos que eu tenha uma tabela grande que contém as informações do usuário e outra tabela que contém vários locais.Então eu uso outra tabela que contém o user_id e o location_id.

Para recuperar os dados, tenho que usar a consulta Left Join.Isso não torna todo o processo mais demorado para ser recuperado, em vez de ter tudo em uma tabela?Por exemplo, eu poderia ter o local como texto na mesma tabela.

EDITAR:Aqui está um exemplo.

CREATE TABLE  `user` (
`id` int(11) NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  `gender` enum('M','F') DEFAULT NULL
);

CREATE TABLE `user_location` (
  `user_id` int(11) NOT NULL,
  `location_id` int(11) NOT NULL
);

CREATE TABLE `location` (
`id` int(11) NOT NULL,
  `location` varchar(45),
  `parent_id` varchar(45) 
);

Observação:Suponha que todos os campos relacionados estejam devidamente indexados entre eles.

Editar:Atualmente tenho um grande banco de dados com usuários que recuperam sua localização por meio de uma tabela de junção conforme descrito acima.Pediram-me para otimizar o banco de dados porque os resultados da pesquisa são lentos.eu já adicionei memcache e melhorou significativamente, mas agora estou pensando sobre Left Joins.

Por exemplo, a consulta atual é algo assim:

SELECT * FROM users 
LEFT JOIN user_location 
ON user_location.user_id = user.id 
LEFT JOIN location
ON location.id = user_location.location_id;

E isso é apenas para obter a localização.Eles possuem vários outros campos que são recuperados por meio de junções e todos são necessários para visualizar o perfil de um usuário.Temos números de telefone, endereços, senhas, D.O.B e muitos outros, todos em tabelas diferentes.

Para criar uma página para o perfil do usuário, preciso enviar ao servidor uma grande consulta.Agora, depois da primeira vez, ele é armazenado em cache e está tudo bem.Mas eu estava me perguntando por que alguém construiria seu banco de dados assim?

Foi útil?

Solução

Se você colocar tudo em uma tabela, terá uma tabela maior e redundante.

Se todas as tabelas estiverem indexadas corretamente, a solução de 3 tabelas será rápida, pois um pequeno número de linhas será lido para cada consulta.

Outras dicas

As tabelas de junção são uma prática muito comum no design de bancos de dados relacionais.Está coberto no banco de dados 101.Se você tiver um relacionamento muitos-para-muitos entre duas entidades, a forma padrão de representá-las é com três tabelas.

Duas das tabelas são tabelas de entidades, com uma chave primária.Uma tabela de junção fica entre eles (logicamente) e contém duas chaves estrangeiras, uma que faz referência a cada tabela de entidade.Freqüentemente, essas duas chaves estrangeiras serão as únicas duas colunas na tabela de junção.

Não consigo entender por que alguém perguntaria se isso é ou não uma boa prática, a menos que nunca tenha abordado o banco de dados 101.

"Por favor, suponha que todos os campos relacionados sejam indexados devidamente entre eles". Não, eu não vou fazer isso.Vejo muitos usuários que nunca ouviram falar de índices "compostos" e muito menos entendem sua importância.

Em particular, você deve ter:

CREATE TABLE user_location(
    # No surrogate id for this table
    user_id     MEDIUMINT UNSIGNED NOT NULL,   -- For JOINing to one table
    location_id MEDIUMINT UNSIGNED NOT NULL,   -- For JOINing to the other table
    # Include other fields specific to the 'relation'
    PRIMARY KEY(user_id, location_id),            -- When starting with user
    INDEX      (location_id, user_id)             -- When starting with location
) ENGINE=InnoDB;

Avançar as notas estão no meu blog.

Sua abordagem com o DB está errada.Uma tabela não é um monte de campos para armazenar dados que você manipula adicionando/removendo colunas sem critérios.A estrutura do banco de dados é o resultado de uma análise.Esta parte do Db nasce de requisitos específicos:Um usuário mora em um ou mais locais.No mesmo local podem residir um ou mais usuários.Um usuário é identificado por um nome e sexo.Um local é identificado por id.Com base nestes requisitos, você identifica 2 entidades:Usuários e locais.Como a associação entre essas entidades é muitos para muitos, transformando o esquema conceitual em ER, você obterá (matematicamente) uma tabela específica referente a UsersLocations, composta (pelo menos) por duas chaves estrangeiras que apontam para ambas as entidades.Como o nome não pode ser usado como chave primária (porque as pessoas podem ter o mesmo nome), você usa um ID (provavelmente com incremento automático).

Se você tem um EAV você só tem de INSERT um valor padrão de location_id = 0 ou 1 e sua descrição seria Indefinido ou Não configurado na tua locations mesa.Faça um gatilho que INSERT por padrão na tabela com o user_id e location_id.

Então, você não precisa usar LEFT JOIN e faça a busca lentamente, apenas um JOIN.Se o usuário tiver o location_id= 0 ou 1 (o que você pegou) retornará o padrão location_name.

A propósito, o LEFT JOIN a sintaxe dependerá do seu índice.Se você tem um índice nesses campos, não vejo problema se o seu users a mesa não é grande (supondo).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a dba.stackexchange
scroll top