Sou o único DBA em nossa empresa e sou relativamente novo na profissão (tendo agora 2,5 anos de experiência). Os desenvolvedores e eu estamos discutindo sobre como projetar adequadamente o banco de dados para um novo software que está sendo desenvolvido. Eles desenvolvem seus aplicativos em módulos e acreditam que ter uma tabela de status privada para cada módulo é melhor, enquanto acredito que ter uma tabela para conter todos os estados gerados internamente (e possivelmente tabelas adicionais para dar algum significado a esses estados) seria melhor. O código de amostra abaixo está escrito em postgresql, pois é o que usamos.
Minha abordagem:
CREATE TABLE status (
status_id SERIAL PRIMARY KEY,
status_code VARCHAR(3) UNIQUE NOT NULL, -- short description
status_description VARCHAR(50) UNIQUE NOT NULL -- long description
);
CREATE TABLE member_status (
status_id INT PRIMARY KEY REFERENCES status (status_id)
);
A abordagem deles:
CREATE TABLE member_status (
status_id SERIAL PRIMARY KEY,
status_code VARCHAR(3) UNIQUE NOT NULL, -- short description
status_description VARCHAR(50) UNIQUE NOT NULL -- long description
);
-- rinse and repeat for every object that may need a status
Eles só veem "problemas" com minha abordagem (que ainda precisam ser claramente articulados) e, embora eu não veja problemas com a abordagem deles, acredito que não seja o melhor design.
Qualquer contribuição sobre qual design é melhor e PORQUÊ seria apreciada.
O principal problema com sua abordagem ocorre quando você deseja manter a integridade referencial da tabela de status.
Suponha que você tenha uma tabela de membros:
Agora, se você deseja impor integridade referencial para garantir que cada membro tenha um status válido, não pode. Isso ocorre porque apenas um subconjunto das linhas de status se aplica aos membros. Como resultado, um membro pode receber um
purchase_order_status
e o RI ainda será aprovado.EDIT2
Em um comentário, você esclareceu que em sua solução, o membro teria RI para a
member_status
tabela de coluna única. Isso sugere que seu design pode ter um grande número de tabelas de coluna única, apenas para controlar a integridade referencial. Agora, sempre que você adicionar um novo status, precisará adicioná-lo a 2 tabelas.Há outro problema com sua
master_status
mesa.status_code
é único. O que significa quepurchase_order
esales_order
não pode usar os mesmos códigos. Esta parece ser uma restrição desnecessariamente severa. No entanto, descartar a restrição exclusiva corre o risco de duplicar os códigos dentro de uma categoria.Portanto, a próxima coisa que você deve considerar é adicionar um
status_type
e impor a restrição exclusiva no tipo e no código. Portanto, seu status_type tenta corrigir o problema subjacente dividindo artificialmente a tabela principal em várias tabelas.Basicamente, o problema se resume a: você está tentando consolidar vários conjuntos distintos de dados em uma única tabela porque há uma semelhança no fato de que algumas de suas colunas se sobrepõem.
Joe Celko escreveu um artigo bastante aprofundado sobre Lookup Tables in SQL .
EDIT Pensando bem, talvez sua abordagem não seja muito parecida com "One True Lookup Table" porque você reconhece a necessidade de tabelas adicionais onde mais detalhes são necessários. A questão do RI ainda permanece.