Eu estava pensando outro dia na normalização, e me ocorreu que não consigo pensar em um momento em que deveria haver um relacionamento 1: 1 em um banco de dados.
Name:SSN
? Eu os teria na mesma mesa.PersonID:AddressID
? Mais uma vez, mesma mesa.
Posso criar um zilhão de exemplos de 1: muitos ou muitos: muitos (com tabelas intermediárias apropriadas), mas nunca um 1: 1.
Estou perdendo algo óbvio?
sql
database-design
one-to-one
database-normalization
Pulsehead
fonte
fonte
Respostas:
Um relacionamento 1: 1 normalmente indica que você particionou uma entidade maior por algum motivo. Freqüentemente, é devido a razões de desempenho no esquema físico, mas também pode ocorrer no lado lógico se se espera que uma grande parte dos dados seja "desconhecida" ao mesmo tempo (nesse caso, você tem 1: 0 ou 1: 1, mas não mais).
Como exemplo de uma partição lógica: você tem dados sobre um funcionário, mas há um conjunto maior de dados que precisam ser coletados, se e somente se eles optarem por ter cobertura de saúde. Eu manteria os dados demográficos referentes à cobertura de saúde em uma tabela diferente para facilitar o particionamento de segurança e evitar transportar esses dados em consultas não relacionadas ao seguro.
Um exemplo de uma partição física seria os mesmos dados hospedados em vários servidores. Posso manter os dados demográficos da cobertura de saúde em outro estado (onde fica o escritório de RH, por exemplo) e o banco de dados primário só pode vincular a ele por meio de um servidor vinculado ... evitando replicar dados confidenciais para outros locais, mas disponibilizando-os para (assumindo aqui raras) consultas que precisam.
O particionamento físico pode ser útil sempre que você tiver consultas que precisem de subconjuntos consistentes de uma entidade maior.
fonte
Um dos motivos é a eficiência do banco de dados. Ter um relacionamento 1: 1 permite dividir os campos que serão afetados durante um bloqueio de linha / tabela. Se a tabela A possui muitas atualizações e a tabela b possui muitas leituras (ou muitas atualizações de outro aplicativo), o bloqueio da tabela A não afeta o que está acontecendo na tabela B.
Outros trazem um bom argumento. A segurança também pode ser um bom motivo, dependendo de como os aplicativos etc. estão atingindo o sistema. Eu tenderia a adotar uma abordagem diferente, mas pode ser uma maneira fácil de restringir o acesso a determinados dados. É realmente fácil negar o acesso a uma determinada mesa rapidamente.
Minha entrada de blog sobre isso.
fonte
Escassez. O relacionamento de dados pode ser tecnicamente 1: 1, mas as linhas correspondentes não precisam existir para cada linha. Portanto, se você tiver vinte milhões de linhas e houver algum conjunto de valores que exista apenas para 0,5% deles, a economia de espaço será grande se você empurrar essas colunas para uma tabela que pode ser pouco preenchida.
fonte
A maioria das respostas altamente classificadas fornece motivos de otimização e otimização do banco de dados muito úteis para relacionamentos 1: 1, mas eu quero focar em nada além de exemplos "inativos" onde os relacionamentos 1: 1 ocorrem naturalmente.
Observe uma característica importante da implementação do banco de dados da maioria desses exemplos: nenhuma informação histórica é mantida sobre o relacionamento 1: 1. Ou seja, esses relacionamentos são 1: 1 em um determinado momento. Se o designer do banco de dados quiser registrar alterações nos participantes do relacionamento ao longo do tempo, os relacionamentos se tornarão 1: M ou M: M; eles perdem sua natureza 1: 1. Com isso entendido, aqui vai:
Relações "Is-A" ou supertipo / subtipo ou herança / classificação: Esta categoria é quando uma entidade é um tipo específico de outra entidade. Por exemplo, poderia haver uma entidade Funcionário com atributos que se aplica a todos os funcionários e, em seguida, entidades diferentes para indicar tipos específicos de funcionários com atributos exclusivos para esse tipo de funcionário, por exemplo, Médico, Contador, Piloto, etc. Esse design evita vários valores nulos, pois muitos funcionários não teriam os atributos especializados de um subtipo específico. Outros exemplos nessa categoria podem ser Product como supertipo e ManufacturingProduct and MaintenanceSupply como subtipos; Animal como supertipo e Cão e Gato como subtipos; etc. Observe que sempre que você tenta mapear uma hierarquia de herança orientada a objetos em um banco de dados relacional (como em um modelo de objeto relacional), esse é o tipo de relacionamento que representa esses cenários.
Relações de "chefe" , como gerente, presidente, presidente etc., em que uma unidade organizacional pode ter apenas um chefe e uma pessoa pode ser chefe de apenas uma unidade organizacional. Se essas regras se aplicarem, você terá um relacionamento 1: 1, como um gerente de um departamento, um CEO de uma empresa etc. Os relacionamentos de "chefe" não se aplicam apenas às pessoas. O mesmo tipo de relacionamento ocorre se houver apenas uma loja como sede de uma empresa ou se apenas uma cidade for a capital de um país, por exemplo.
Alguns tipos de alocação escassa de recursos , por exemplo, um funcionário pode receber apenas um carro da empresa por vez (por exemplo, um caminhão por caminhoneiro, um táxi por motorista de táxi, etc.). Um colega me deu esse exemplo recentemente.
Casamento (pelo menos em jurisdições legais onde a poligamia é ilegal): uma pessoa pode ser casada com apenas uma outra pessoa de cada vez. Eu recebi esse exemplo de um livro que o usou como exemplo de um relacionamento unário 1: 1 quando uma empresa registra casamentos entre seus funcionários.
Reservas correspondentes : quando uma reserva exclusiva é feita e depois atendida como duas entidades separadas. Por exemplo, um sistema de aluguel de carros pode registrar uma reserva em uma entidade e, em seguida, um aluguel real em uma entidade separada. Embora essa situação possa ser projetada alternativamente como uma entidade, pode fazer sentido separar as entidades, pois nem todas as reservas são cumpridas e nem todos os aluguéis exigem reservas, e as duas situações são muito comuns.
Repito a ressalva que fiz anteriormente de que a maioria desses relacionamentos é de 1: 1 somente se nenhuma informação histórica for registrada. Portanto, se um funcionário mudar de função em uma organização, ou se um gerente assumir a responsabilidade de um departamento diferente, ou se um funcionário for transferido para um veículo ou se alguém for viúvo e se casar novamente, os participantes do relacionamento poderão mudar. Se o banco de dados não armazenar nenhum histórico anterior sobre esses relacionamentos 1: 1, eles permanecerão relacionamentos legítimos 1: 1. Mas se o banco de dados registra informações históricas (como adicionar datas de início e término para cada relacionamento), elas praticamente se transformam em relacionamentos M: M.
Há duas exceções notáveis na nota histórica: Primeiro, alguns relacionamentos mudam tão raramente que as informações históricas normalmente não seriam armazenadas. Por exemplo, a maioria dos relacionamentos IS-A (por exemplo, tipo de produto) é imutável; isto é, eles nunca podem mudar. Assim, o ponto de registro histórico é discutível; estes sempre seriam implementados como relacionamentos naturais 1: 1. Segundo, a loja de relacionamento reserva-aluguel data separadamente, pois a reserva e o aluguel são eventos independentes, cada um com suas próprias datas. Como as entidades têm suas próprias datas, em vez de o relacionamento 1: 1 ter uma data de início, eles permaneceriam como relacionamentos 1: 1, mesmo que as informações históricas sejam armazenadas.
fonte
Sua pergunta pode ser interpretada de várias maneiras, devido à maneira como você a formulou. As respostas mostram isso.
Definitivamente, pode haver relacionamentos 1: 1 entre itens de dados no mundo real. Nenhuma pergunta sobre isso. O relacionamento "é um" geralmente é um para um. Um carro é um veículo. Um carro é um veículo. Um veículo pode ser um carro. Alguns veículos são caminhões; nesse caso, um veículo não é um carro. Várias respostas abordam essa interpretação.
Mas acho que o que você realmente está perguntando é ... quando existem relacionamentos 1: 1, as tabelas devem ser divididas? Em outras palavras, você deve ter duas tabelas que contêm exatamente as mesmas chaves? Na prática, a maioria de nós analisa apenas chaves primárias, e não outras chaves candidatas, mas essa pergunta é um pouco diferente.
As regras de normalização para 1NF, 2NF e 3NF nunca exigem a decomposição (divisão) de uma tabela em duas tabelas com a mesma chave primária. Ainda não descobri se colocar um esquema em BCNF, 4NF ou 5NF pode resultar em duas tabelas com as mesmas chaves. Em cima da minha cabeça, vou adivinhar que a resposta é não.
Há um nível de normalização chamado 6NF. A regra de normalização para 6NF pode definitivamente resultar em duas tabelas com a mesma chave primária. O 6NF tem a vantagem sobre o 5NF de que NULLS podem ser completamente evitados. Isso é importante para alguns, mas não para todos os designers de banco de dados. Eu nunca me preocupei em colocar um esquema em 6NF.
No 6NF, os dados ausentes podem ser representados por uma linha omitida, em vez de uma linha com um NULL em alguma coluna.
Há outros motivos além da normalização para dividir tabelas. Às vezes, as tabelas divididas resultam em melhor desempenho. Com alguns mecanismos de banco de dados, você pode obter os mesmos benefícios de desempenho particionando a tabela em vez de realmente dividi-la. Isso pode ter a vantagem de manter o design lógico fácil de entender, enquanto fornece ao mecanismo de banco de dados as ferramentas necessárias para acelerar as coisas.
fonte
Eu os uso principalmente por alguns motivos. Uma é a diferença significativa na taxa de alteração de dados. Algumas de minhas tabelas podem ter trilhas de auditoria nas quais rastreio versões anteriores de registros, se apenas desejar rastrear versões anteriores de 5 de 10 colunas dividindo essas 5 colunas em uma tabela separada com um mecanismo de trilha de auditoria mais eficiente. Além disso, posso ter registros (digamos, para um aplicativo de contabilidade) que são apenas para gravação. Você não pode alterar os valores em dólares ou a conta em que estavam, se cometer um erro, precisará fazer um registro correspondente para ajustar o registro incorreto e criar uma entrada de correção. Tenho restrições na tabela que impõem o fato de que elas não podem ser atualizadas ou excluídas, mas posso ter alguns atributos para esse objeto que são maleáveis, esses são mantidos em uma tabela separada sem a restrição de modificação. Outra vez que faço isso é em aplicativos de registros médicos. Existem dados relacionados a uma visita que não podem ser alterados após o encerramento da sessão e outros dados relacionados a uma visita que podem ser alterados após a saída. Nesse caso, dividirei os dados e acionarei a tabela bloqueada, rejeitando atualizações na tabela bloqueada quando desconectado, mas permitindo atualizações nos dados nos quais o médico não está assinando.
Outro pôster comentou que 1: 1 não estava sendo normalizado, eu discordaria disso em algumas situações, especialmente na subtipagem. Digamos que eu tenha uma tabela de funcionários e a chave primária seja o SSN (é um exemplo, vamos salvar o debate sobre se essa é uma boa chave ou não para outro encadeamento). Os funcionários podem ser de tipos diferentes, por exemplo, temporários ou permanentes e, se forem permanentes, terão mais campos a serem preenchidos, como o número de telefone do escritório, que só deve ser nulo se o tipo = 'Permanente'. Em um terceiro banco de dados de formulário normal, a coluna deve depender apenas da chave, ou seja, o funcionário, mas na verdade depende do funcionário e do tipo; portanto, um relacionamento 1: 1 é perfeitamente normal e desejável nesse caso. Isso também evita tabelas excessivamente esparsas, se eu tiver 10 colunas normalmente preenchidas,
fonte
O cenário mais comum em que consigo pensar é quando você tem BLOB's. Digamos que você queira armazenar imagens grandes em um banco de dados (normalmente, não é a melhor maneira de armazená-las, mas às vezes as restrições o tornam mais conveniente). Você normalmente deseja que o blob esteja em uma tabela separada para melhorar as pesquisas dos dados que não são de blob.
fonte
Em termos de ciência pura, sim, eles são inúteis.
Em bancos de dados reais, às vezes é útil manter um campo raramente usado em uma tabela separada: para acelerar consultas usando esse e somente esse campo; para evitar bloqueios, etc.
fonte
Em vez de usar visualizações para restringir o acesso aos campos, às vezes faz sentido manter os campos restritos em uma tabela separada à qual apenas alguns usuários têm acesso.
fonte
Também posso pensar em situações em que você tem um modelo OO em que você usa herança, e a árvore de herança precisa ser mantida no banco de dados.
Por exemplo, você tem uma classe Pássaro e Peixe que ambos herdam de Animal. No seu banco de dados, você poderia ter uma tabela 'Animal', que contém os campos comuns da classe Animal, e a tabela Animal tem um relacionamento individual com a tabela Bird e um relacionamento individual com o Fish tabela.
Nesse caso, você não precisa ter uma tabela Animal que contém muitas colunas anuláveis para conter as propriedades Bird e Fish, onde todas as colunas que contêm dados de Fish são definidas como NULL quando o registro representa um pássaro.
Em vez disso, você tem um registro na tabela Birds que possui um relacionamento individual com o registro na tabela Animal.
fonte
Os relacionamentos 1-1 também são necessários se você tiver muita informação. Há uma limitação de tamanho de registro em cada registro da tabela. Às vezes, as tabelas são divididas em duas (com as informações mais comumente consultadas na tabela principal) apenas para que o tamanho do registro não seja muito grande. Os bancos de dados também são mais eficientes na consulta se as tabelas são estreitas.
fonte
É também uma maneira de estender uma tabela que já está em produção com menos risco (percebido) do que uma alteração "real" no banco de dados. Ver um relacionamento 1: 1 em um sistema legado geralmente é um bom indicador de que os campos foram adicionados após o design inicial.
fonte
No SQL, é impossível impor um relacionamento 1: 1 entre duas tabelas que é obrigatório em ambos os lados (a menos que as tabelas sejam somente leitura). Para propósitos mais práticos, um relacionamento "1: 1" no SQL realmente significa 1: 0 | 1.
A incapacidade de oferecer suporte à cardinalidade obrigatória em restrições referenciais é uma das sérias limitações do SQL. Restrições "adiadas" não contam realmente porque são apenas uma maneira de dizer que a restrição não é impingida em algum momento.
fonte
Se você estiver usando os dados com um dos ORMs populares, convém dividir uma tabela em várias tabelas para corresponder à sua Hierarquia de Objetos.
fonte
Descobri que quando faço um relacionamento 1: 1 é totalmente por uma razão sistêmica, não por uma razão relacional.
Por exemplo, descobri que colocar os aspectos reservados de um usuário em uma tabela e colocar os campos editáveis do usuário em uma tabela diferente permite escrever logicamente essas regras sobre permissões nesses campos muito mais fácil.
Mas você está correto, em teoria, os relacionamentos 1: 1 são completamente inventados e são quase um fenômeno. No entanto, logicamente, permite que os programas e otimizações abstrajam o banco de dados com mais facilidade.
fonte
Na maioria das vezes, pensa-se que os desenhos sejam 1: 1 até que alguém pergunte "bem, por que não pode ser 1: muitos"? O divórcio prematuro dos conceitos é feito em antecipação a esse cenário comum. Pessoa e endereço não se vinculam tão firmemente. Muitas pessoas têm vários endereços. E assim por diante...
Normalmente, dois espaços de objetos separados implicam que um ou ambos possam ser multiplicados (x: muitos). Se dois objetos eram verdadeiramente, verdadeiramente 1: 1, mesmo filosoficamente, então é mais um relacionamento é. Esses dois "objetos" são na verdade partes de um objeto inteiro.
fonte
informações estendidas necessárias apenas em certos cenários. em aplicativos herdados e linguagens de programação (como RPG), em que os programas são compilados sobre as tabelas (por isso, se a tabela mudar, é necessário recompilar o (s) programa (s)). Os arquivos de tag along também podem ser úteis nos casos em que você precisa se preocupar com o tamanho da tabela.
fonte
Na maioria das vezes, é mais uma construção física do que lógica. É comumente usado para particionar verticalmente uma tabela para aproveitar a divisão de E / S entre dispositivos físicos ou outras otimizações de consulta associadas à segregação de dados acessados com menos frequência ou dados que precisam ser mantidos mais seguros que o restante dos atributos no mesmo objeto (SSN, salário, etc).
A única consideração lógica que prescreve um relacionamento 1-1 é quando determinados atributos se aplicam apenas a algumas das entidades. No entanto, na maioria dos casos, existe uma maneira melhor / mais normalizada de modelar os dados por meio da extração da entidade.
fonte
A melhor razão que eu posso ver para um relacionamento 1: 1 é um SuperType SubType de design de banco de dados. Criei uma estrutura de dados do Real Estate MLS com base nesse modelo. Havia cinco feeds de dados diferentes; Residencial, Comercial, Multifamiliar, Hotéis e Terrenos.
Criei uma propriedade chamada SuperType que continha dados comuns a cada um dos cinco feeds de dados separados. Isso permitiu pesquisas "simples" muito rápidas em todos os tipos de dados.
Criei cinco subtipos separados que armazenavam os elementos de dados exclusivos para cada um dos cinco feeds de dados. Cada registro SuperType tinha um relacionamento 1: 1 com o registro SubType apropriado.
Se um cliente quisesse uma pesquisa detalhada, ele teria que selecionar um tipo Super-Sub, por exemplo PropertyResidential.
fonte
Na minha opinião, um relacionamento 1: 1 mapeia uma herança de classe em um RDBMS. Há uma tabela A que contém os atributos comuns, ou seja, o status da classe de partente. Cada status de classe herdado é mapeado no RDBMS com uma tabela B com um relacionamento 1: 1 com a tabela A, contendo os atributos especializados. O nome da tabela A também contém um campo "type" que representa a funcionalidade "casting"
Tchau Mario
fonte
Você pode criar uma tabela de relacionamento um para um se houver algum benefício significativo de desempenho. Você pode colocar os campos raramente usados em uma tabela separada.
fonte
Os relacionamentos 1: 1 realmente não fazem sentido se você estiver na normalização, pois qualquer coisa que seria 1: 1 seria mantida na mesma tabela.
No mundo real, porém, muitas vezes é diferente. Você pode dividir seus dados para corresponder à interface de aplicativos.
fonte
Possivelmente se você tiver algum tipo de objeto digitado no seu banco de dados.
Digamos que em uma tabela T1 você tenha as colunas C1, C2, C3 ... com uma relação de um para um. Está tudo bem, está na forma normalizada. Agora, digamos que na tabela T2, você tenha as colunas C1, C2, C3,… (os nomes podem diferir, mas digamos que os tipos e a função sejam os mesmos) com uma relação de um para um também. Não há problema em T2 pelos mesmos motivos que em T1.
Nesse caso, no entanto, vejo um ajuste para uma tabela separada T3, contendo C1, C2, C3 ... e uma relação de um para um de T1 para T3 e de T2 para T3. Eu vejo ainda mais um ajuste se existir outra tabela, com a qual já exista uma para vários C1, C2, C3 ... digamos da tabela A para várias linhas na tabela B. Então, em vez de T3, você usa B e tem uma relação um a um de T1 a B, o mesmo para T2 a B e ainda a mesma relação múltipla de A a B.
Acredito que a normalização não concorda com isso, e isso pode ser uma idéia fora dela: identificar tipos de objetos e mover objetos do mesmo tipo para seu próprio pool de armazenamento, usando uma relação de um para um de algumas tabelas e uma para vários relação de algumas outras tabelas.
fonte
É desnecessário para fins de segurança, mas existem maneiras melhores de realizar verificações de segurança. Imagine, você cria uma chave que pode abrir apenas uma porta. Se a chave puder abrir qualquer outra porta, você deverá tocar o alarme. Em essência, você pode ter "CitizenTable" e "VotingTable". Cidadão Um voto para o Candidato Um que está armazenado na Mesa de Votação. Se um cidadão aparecer novamente na mesa de votação, então deve ser um alarme. Seja um conselho, este é um relacionamento individual, porque não estamos nos referindo ao campo do candidato, estamos nos referindo à mesa de votação e à mesa do cidadão.
Exemplo:
Então, se virmos a mesa de votação da seguinte forma:
Poderíamos dizer que o cidadão número 3 é um mentiroso que enganou Bern Nie. Apenas um exemplo.
fonte
Quando você está lidando com um banco de dados de um produto de terceiros, provavelmente não deseja alterar o banco de dados para evitar um acoplamento rígido. mas você pode ter dados que correspondem 1: 1 com os dados deles
fonte
Em qualquer lugar, duas entidades totalmente independentes compartilham um relacionamento individual. Deve haver muitos exemplos:
pessoa <-> dentista (é 1: N, está errado!)
pessoa <-> médico (é 1: N, também está errado!)
pessoa <-> cônjuge (é 1: 0 | 1, então é quase todo errado!)
EDIT: Sim, esses foram exemplos muito ruins, principalmente se eu estava sempre procurando um 1: 1, não um 0 ou 1 de cada lado. Eu acho que meu cérebro estava disparando errado :-)
Então, vou tentar novamente. Depois de um pouco de reflexão, acontece que a única maneira de ter duas entidades separadas que devem (no que diz respeito ao software) estar juntas o tempo todo é que elas existam juntas em uma categorização mais alta. Então, se e somente se você cair em uma decomposição mais baixa, as coisas são e devem ser separadas, mas no nível superior elas não podem viver uma sem a outra. Contexto, então é a chave.
Para um banco de dados médico, convém armazenar informações diferentes sobre regiões específicas do corpo, mantendo-as como uma entidade separada. Nesse caso, um paciente tem apenas uma cabeça e eles precisam dela, ou não são pacientes. (Eles também têm um coração e vários outros órgãos únicos necessários). Se você estiver interessado em rastrear cirurgias, por exemplo, cada região deve ser uma entidade separada e única.
Em um sistema de produção / estoque, se você estiver acompanhando a montagem de veículos, certamente desejará assistir o motor progredir de forma diferente da carroceria do carro, mas há um relacionamento individual. Um cuidado deve ter um motor e apenas um (ou não seria mais um 'carro'). Um motor pertence a apenas um carro.
Em cada caso, você poderia produzir as entidades separadas como um grande registro, mas, dado o nível de decomposição, isso seria errado. São, nesses contextos específicos, entidades verdadeiramente independentes, embora possam não parecer assim em um nível superior.
Paulo.
fonte