A resposta depende um pouco se você está limitado a freeware como PostGreSQL (não totalmente compatível com SQL), ou se você está pensando em SQL (ou seja, compatível com SQL) e grandes bancos de dados.
Em conformidade com SQL, Arquitetura aberta bancos de dados, onde há muitos aplicativos usando um banco de dados e muitos usuários usando diferentes ferramentas de relatório (não apenas os aplicativos) para acessar os dados, padrões, normalização e requisitos de arquitetura aberta são importantes.
Apesar das pessoas que tentam mudar a definição de "normalização", etc. para se adequar ao seu propósito em constante mudança, a Normalização (a ciência) não mudou.
-
se você tiver valores de dados como {Open; Closed; etc
} repetido nas tabelas de dados, que é duplicação de dados , um simples erro de normalização:se esses valores forem alterados, talvez seja necessário atualizar milhões de linhas, o que é um design muito limitado.
-
Esses valores devem ser normalizados em uma tabela de referência ou pesquisa, com um curtoCHAR(2)
PK:
O Open C Closed U [NotKnown]
-
Os valores de dados {Open;Closed;etc
} não são mais duplicados nos milhões de linhas. Também economiza espaço.
-
o segundo ponto é a facilidade de mudança, seClosed
foram alterados paraExpired
, novamente, uma linha precisa ser alterada e isso se reflete em todo o banco de dados; enquanto nos arquivos não normalizados, milhões de linhas precisam ser alteradas.
-
Adicionando novos valores de dados , por exemplo. (H,HalfOpen
) é simplesmente uma questão de inserir uma linha.
-
-
in Arquitetura Aberta termos, a tabela Lookup é uma tabela comum. Ele existe no catálogo [compatível com SQL]; contanto que aFOREIGN KEY
relação foi definida, a ferramenta de relatório também pode encontrá-la.
-
ENUM
é um não-SQL, não o use. No SQL, o "enum" é uma tabela de pesquisa.
-
O próximo ponto diz respeito ao significado da chave.
- Se a chave não tiver sentido para o usuário, tudo bem, use um {
INT;BIGINT;GUID;etc
} ou o que for adequado; não os numere de forma incremental; permitir "lacunas". - Mas se a chave for significativa para o usuário, não use um número sem significado, use uma chave relacional significativa.
- Se a chave não tiver sentido para o usuário, tudo bem, use um {
-
Agora algumas pessoas entrarão na tangente em relação à permanência dos PKs. Isso é um ponto à parte. Sim, claro, sempre use um valor estável para um PK (não "imutável", porque tal coisa não existe e uma chave gerada pelo sistema não fornece exclusividade de linha).
-
{M,F
} é improvável que mude
-
se você usou {0,1,2,4,6
}, bem, não mude, por que você quer. Esses valores deveriam ser sem sentido, lembre-se, apenas uma chave significativa precisa ser alterada.
-
se você usar chaves significativas, use códigos alfabéticos curtos, que os desenvolvedores possam entender prontamente (e inferir a descrição longa). Você apreciará isso apenas quando codificarSELECT
e perceba que você não precisaJOIN
cada tabela de pesquisa. Usuários avançados também, apreciá-lo.
-
-
Como os PKs são estáveis, principalmente em tabelas de pesquisa, você pode codificar com segurança:
WHERE status_code = 'O' -- Open
Você não precisaJOIN
a tabela de pesquisa e obtenha o valor de dadosOpen
, como desenvolvedor, você deve saber o que significam os PKs de pesquisa.
Por último, se o banco de dados fosse grande e suportasse funções de BI ou DSS ou OLAP além de OLTP (como bancos de dados normalizados adequadamente podem), então a tabela de pesquisa é na verdade uma dimensão ou vetor, em Dimension-Fact análises. Se não estivesse lá, então teria que ser adicionado, para satisfazer os requisitos desse software, antes que tais análises possam ser montadas.
- Se você fizer isso em seu banco de dados desde o início, não precisará atualizá-lo (e o código) posteriormente.
Seu exemplo
SQL é uma linguagem de baixo nível, portanto, é complicada, especialmente quando se trata de
JOINs
. Isso é o que temos, então precisamos apenas aceitar o estorvo e lidar com isso. Seu código de exemplo está bom. Mas formas mais simples podem fazer a mesma coisa. Uma ferramenta de relatório geraria:
SELECT p.*,
s.name
FROM posts p,
status s
WHERE p.status_id = s.status_id
AND p.status_id = 'O'
Outro exemplo
Para sistemas bancários, onde usamos códigos curtos que são significativos (uma vez que são significativos, não os alteramos com as estações, apenas adicionamos a eles), dada uma tabela de pesquisa como (cuidadosamente escolhido, semelhante aos códigos de país ISO) :
Eq Equity
EqCS Equity/Common Share
OTC OverTheCounter
OF OTC/Future
Código como este é comum:
WHERE InstrumentTypeCode LIKE "Eq%"
E os usuários da GUI escolheriam o valor em uma lista suspensa que exibe
{
Equity/Common Share;Over The Counter
},não {
Eq;OTC;OF
}, não {M;F;U
}.Sem uma tabela de pesquisa, você não pode fazer isso, nem nos aplicativos, nem na ferramenta de relatório.