Pergunta

Atualmente, estou escrevendo meu primeiro aplicativo PHP verdadeiramente e gostaria de saber como projetar/projetar/implementar as visualizações MySQL corretamente;

No meu caso, os dados do usuário de caso estão espalhados por várias tabelas (como conseqüência da normalização do banco de dados) e eu estava pensando em usar uma visão para agrupar dados em uma tabela grande:

CREATE VIEW `Users_Merged` (
name,
surname,
email,
phone,
role
) AS (
SELECT name, surname, email, phone, 'Customer'
FROM `Customer`
)
UNION (

SELECT name, surname, email, tel, 'Admin'
FROM `Administrator`
)
UNION (

SELECT name, surname, email, tel, 'Manager'
FROM `manager`
);

Dessa forma, posso usar os dados da visualização do aplicativo PHP facilmente, mas realmente não sei quanto isso pode afetar o desempenho.

Por exemplo:

SELECT * from `Users_Merged` WHERE role = 'Admin';

É a maneira certa de filtrar os dados da View ou devo filtrar antes de criar a própria visualização? (Preciso que isso tenha uma lista de usuários e a funcionalidade para filtrá -los por função).

EDITAR

Especificamente, o que estou tentando obter é desnormalização de três tabelas em uma. Minha solução está correta?Veja desnormalização na Wikipedia

Foi útil?

Solução

Em geral, o mecanismo de banco de dados executará a otimização para você. Isso significa que o mecanismo descobrirá que a tabela de usuários precisa ser filtrada antes de ser unida às outras tabelas.

Então, vá em frente e use sua visualização e deixe o banco de dados se preocupar com isso.

Se você detectar um desempenho ruim mais tarde, use o MySQL, explique para obter o MySQL para dizer o que está fazendo.

PS: Seu design de dados permite apenas uma função por usuário, é isso que você queria? Nesse caso, e se a consulta de exemplo que você deu é uma que você pretende executar com frequência, indexe a coluna de função nos usuários.

Outras dicas

Se você tem <1000 usuários (o que parece provável), não importa como você faz isso. Se é improvável que a lista de usuários mude por longos períodos de tempo, o melhor que você provavelmente pode fazer em termos de desempenho é carregar a lista de usuários na memória e não ir ao banco de dados. Mesmo que os dados do usuário mudassem enquanto isso, você poderia atualizar a estrutura da memória e o banco de dados e, novamente, não precisar ler as informações do usuário do banco de dados.

Você provavelmente estaria muito melhor normalizando os administradores, usuários, gerentes e o que você fez em uma mesa uniforme com uma coluna discriminadora "função" que economizaria muita duplicação, que é essencialmente a razão para fazer a normalização no primeiro Lugar, colocar. Você pode adicionar os detalhes específicos da função a tabelas distintas que você usa com a tabela de usuários em uma junção.

Sua consulta pode parecer tão simples quanto:

SELECT
   `Name`, `Surname`, `Email`, `Phone`, `Role`
FROM `User`
WHERE 
    `User`.`Role` IN('Administrator','Manager','Customer', ...)

O que também é mais fácil para o banco de dados processar do que um conjunto de unions

Se você der um passo adiante, poderá adicionar um UserRoleCoupling Tabela (em vez do Role coluna in User) que possui todas as funções que um usuário possui por usuário:

CREATE TABLE `UserRoleCoupling` (
    UserID INT NOT NULL,  -- assuming your User table has and ID column of INT
    RoleID INT NOT NULL,
    PRIMARY KEY(UserID, RoleID)
);

E coloque as informações reais de função em uma tabela separada também:

CREATE TABLE `Role` (
    ID INT NOT NULL UNIQUE AUTO_INCREMENT,
    Name VARCHAR(64) NOT NULL
    PRIMARY KEY (Name)
)

Agora você pode ter várias funções por usuário e usar consultas como

SELECT
    `U`.`Name`
   ,`U`.`Surname`
   ,`U`.`Email`
   ,`U`.`Phone`
   ,GROUP_CONCAT(`R`.`Name`) `Roles`
FROM `User`
INNER JOIN `UserGroupCoupling` `UGC` ON `UGC`.`UserID` = `User`.`ID`
INNER JOIN `Role` `R` ON `R`.`ID` = `UGC`.`RoleID`
GROUP BY
    `U`.`Name`, `U`.`Surname`, `U`.`Email`, `U`.`Phone`

O que te daria o básico User detalhes e uma lista separada de vírgula de todos os atribuídos Role nomes.

Em geral, a melhor maneira de normalizar uma estrutura de banco de dados é tornar as tabelas o mais genéricas possível sem ser redundante; portanto, não adicione detalhes do administrador ou do cliente à tabela de usuários, mas use um relacionamento entre User e Administrator Para encontrar os detalhes específicos do administrador. A maneira como você está fazendo isso agora não é realmente normalizada.

Vou ver se consigo encontrar meu livro favorito sobre a normalização do banco de dados e postar o ISBN quando tiver tempo mais tarde.

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