AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 321543
Accepted
soger
soger
Asked: 2022-12-30 09:56:03 +0800 CST2022-12-30 09:56:03 +0800 CST 2022-12-30 09:56:03 +0800 CST

O conteúdo misto em uma coluna é um design ruim?

  • 772

Tenho um colega que vive colocando conteúdo misto em uma coluna. Por exemplo, este caso atual com o qual estou lutando é uma coluna chamada "opts", que é uma matriz de inteiros. Dependendo de um tipo que nem está presente na linha atual, você terá que juntar outra tabela para descobrir isso, esta coluna pode conter:

  • um 0 ou um 1 - significando um estado ligado/desligado
  • uma lista de IDs de uma tabela
  • uma lista de IDs de uma segunda tabela
  • null em qualquer outro caso

Para mim, isso parece mais desordem do que dados organizados. Então, existe um conceito de design de banco de dados que isso viola ou é apenas meu TOC? Quais devem ser meus argumentos quando tento persuadi-lo a não fazer mais isso?

Gostaria de acrescentar que os IDs da tabela não precisam de chaves estrangeiras por motivos que não vale a pena entrar, o colega faz isso com outras coisas também, por exemplo outra coluna em outra tabela tem uma string ou um texto json . O que eu faria nesses casos é ter mais colunas, uma para cada caso, e preencher apenas uma delas e deixar as demais como nulas.

database-design
  • 1 1 respostas
  • 44 Views

1 respostas

  • Voted
  1. Best Answer
    SEarle1986
    2022-12-30T16:13:40+08:002022-12-30T16:13:40+08:00

    Primeiro estou fazendo algumas suposições:

    • "Uma lista de IDs" significa uma string separada por vírgula, como 1,2,3,4,5etc
    • Sua coluna optsé um tipo de dados de string como VARCHAR / NVARCHAR / CHAR etc

    Você não menciona seu DBMS. Minha resposta é baseada no SQL Server, então algumas das coisas que mencionei podem não ser relevantes para outros DBMS

    Para mim, o padrão que você descreve é ​​"One True lookup table (OTLT)", onde você tem uma única tabela de várias entidades diferenciadas por alguma chave ou valor, por exemplo:

    +----+------------+-------+---------------------+
    | ID |  category  | Name  |     DateCreated     |
    +----+------------+-------+---------------------+
    |  1 | Person     | John  | 2022-12-29T00:00:00 |
    |  2 | Person     | Jim   | 2022-12-29T01:00:00 |
    |  3 | Department | I.T   | 2022-12-29T02:00:00 |
    +----+------------+-------+---------------------+
    

    Isso pode ser usado porque quando um novo tipo de entidade é criado, ele pode ser criado inserindo dados em uma tabela em vez de alterar o esquema do banco de dados. Pode potencialmente ser válido quando os diferentes tipos de entidades têm propriedades comuns (no caso acima - um nome e uma data de criação)

    No entanto, começa a cair quando queremos adicionar novas propriedades a uma entidade, por exemplo, a idade de uma pessoa. Nesse caso, adicionaríamos uma coluna de idade à tabela, mas o valor nessa coluna teria significado apenas para algumas das linhas da tabela; isso pode rapidamente se tornar confuso e difícil de trabalhar.

    Algumas reflexões sobre por que o OTLT e o armazenamento de listas delimitadas por vírgulas são ruins

    Para facilitar a explicação, direi que você tem uma linha que possui uma lista de PersonIDs que são armazenados nesta tabela por algum motivo e que você tem uma tabela de pessoa separada onde PersonID é exclusivo

    • Falta de restrição - se um determinado tipo de entidade requer um 1 ou um 0, mas a coluna é VARCHAR, não há nada para impedir que algum outro valor ilegal seja inserido, como 'abc' (talvez uma restrição CHECK, mas é provável que se torne complicada, propenso a erros e precisa ser atualizado toda vez que uma nova categoria é criada)
    • Se precisarmos nos juntar à tabela de pessoas para obter qualquer informação sobre uma ou mais pessoas na lista de ID, teremos que fazer uma divisão de string que pode ser ruim para o desempenho, pois também depende da lista delimitada por vírgulas sendo inserido em um formato padrão
    • Não podemos ver facilmente todas as pessoas na tabela de pessoas que não estão listadas nesta tabela (novamente, conseguiríamos isso por meio de uma antijunção à esquerda)
    • A indexação será quase impossível
    • É mais provável que a tabela cause um problema de bloqueio em seu banco de dados, pois mais consultas a usarão, a maioria será ineficiente e lenta pelos motivos mencionados acima, o que significa que os bloqueios serão mais longos e as consultas em espera esperarão mais
    • Você mencionou que os dados não precisam ser uma chave estrangeira, mas se isso acontecer no futuro, você terá um trabalho em mãos para alterar o esquema do banco de dados
    • Armazenamento - supondo que esta coluna seja VARCHAR, os requisitos de armazenamento serão maiores do que se os tipos de dados corretos fossem usados ​​(armazenar 1 ou 0 como um tipo de dados BIT custa 1 byte, VARCHAR custaria 3)
    • Dependendo do comprimento da coluna VARCHAR, isso pode aumentar enormemente a quantidade de memória necessária para executar consultas - se o SQL Server precisar classificar essa coluna, ele assume que cada linha contém um valor VARCHAR com metade do tamanho do comprimento varchar e usa essa estimativa para conceder a quantidade apropriada de memória. Se sua coluna for VARCHAR(MAX) e o otimizador de consulta precisar classificar essa coluna, seu servidor poderá ficar sem memória rapidamente e novas consultas terão que esperar até que as existentes sejam concluídas (conhecido como RESOURCE_SEMAPHORE waits)
    • É provável que você introduza conversões implícitas ao comparar a coluna com outra coisa, o que geralmente é ruim para estimativa e pode causar vários problemas de desempenho
    • Permissões - e se eu quiser que um usuário possa atualizar departamentos, mas não pessoas, mas ambos estão armazenados na mesma tabela?

    Quanto aos conceitos de design, as listas delimitadas por vírgulas violam a primeira forma normal e o OTLT potencialmente viola a segunda forma normal

    FWIW, eu vivi a dor que esses padrões causam e eles são apenas IMO desagradáveis. Convencer aqueles que os criaram a eliminá-los provavelmente exigirá testes que evidenciem os pontos acima - ao testar, não pense necessariamente em quantos dados você tem agora, pense em 1, 3, 5 anos

    • 1

relate perguntas

  • Os índices filtrados podem ajudar a melhorar as consultas baseadas em uma hora inserida ou isso deve ser evitado?

  • Qual é a diferença entre os tipos de dados MySQL VARCHAR e TEXT?

  • É melhor armazenar os valores calculados ou recalculá-los a pedido? [duplicado]

  • Armazenar vs calcular valores agregados

  • Quais são algumas maneiras de implementar um relacionamento muitos-para-muitos em um data warehouse?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve