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 / 72542
Accepted
reox
reox
Asked: 2014-07-29 00:48:35 +0800 CST2014-07-29 00:48:35 +0800 CST 2014-07-29 00:48:35 +0800 CST

Armazena dados n:m com a maioria das tuplas n:1

  • 772

Eu tenho essas tabelas:

create table data (
    id int identity not null,
    ref int not null
);

create table reference (
    refid int not null
);

com aproximadamente 2 milhões de linhas em dados e aproximadamente 200 mil linhas em referência. Eu adiciono cerca de 5.000 linhas aos dados todos os dias, resultando em 500-5.000 linhas adicionais em referência por dia.

Na maioria dos casos, preciso salvar apenas uma referência para uma coluna de dados (várias entradas de dados podem ter a mesma referência), mas em alguns casos (atualmente cerca de 0,1%) preciso salvar mais de uma referência.

Eu provavelmente poderia usar uma terceira tabela como:

create table data_reference (
     dataid int not null,
     refid int not null
);

criar um mapeamento an:m mas para a maioria dos valores não vai ter nenhum ganho aqui, vai apenas criar outro join...

Eu também poderia criar uma segunda coluna em cada linha de dados, porque na maioria dos casos eu tenho apenas uma referência adicional (mas em teoria poderia haver mais) e salvar null se nenhuma outra referência estiver lá - o que me parece muito ruim porque pode haver tuplas com 3 ou mais referências.

Existe uma maneira eficiente e fácil de manter para salvar esses dados?

sql-server database-design
  • 2 2 respostas
  • 124 Views

2 respostas

  • Voted
  1. Best Answer
    Michael Green
    2014-07-29T05:04:44+08:002014-07-29T05:04:44+08:00

    Usar uma tabela intermediária é a maneira correta de fazer isso. Com índices adequados e boa manutenção não vai prejudicar muito o desempenho.

    Evite a solução de várias colunas ( refid1, refid2etc.) - isso está repetindo grupos e não está devidamente normalizado. Além disso, suas consultas degenerarão em um café da manhã canino de cláusulas OR e instruções CASE, o que prejudicará o desempenho.

    Você pode obter algum benefício ao subdigitar suas datalinhas, então a maioria usa seu arranjo atual, mas aqueles com vários referenceusam um diferente. Suas consultas serão UNION ALLos dois conjuntos para obter o total. Eu realmente duvido que a sobrecarga disso compense a junção redundante para arquivos data_reference.

    O esquema subtipado ficaria assim:

    create table data (
        id int identity not null,
        ref int not null,       -- set to a standard value for rows with >1 reference.
        is_single_reference bit not null
    );
    
    create table reference (
        refid int not null
    );
    
    create table data_reference (
         dataid int not null,
         refid int not null
    );
    

    A consulta seria algo como:

    select
        <whatever>
    from data as d
    inner join reference as r
        on d.ref = r.refid
    where d.is_single_reference = 1
    
    union all
    
    select
        <whatever>
    from data as d
    inner join data_reference as dr
        on dr.dataid= d.id
    inner join reference as r
        on r.refid = dr.refid
    where d.is_single_reference = 0;
    

    Isso é bastante feio. Você teria sorte se evitasse duas varreduras de arquivos data. Idealmente, você desejaria índices filtrados, mas o IIRC não está disponível até o SQL Server 2008. O aplicativo teria que saber quantas referencelinhas havia por data, definir sinalizadores de acordo e mantê-los se o número fosse alterado. Basta usar a abordagem n:m.

    • 1
  2. blobbles
    2014-07-29T01:13:23+08:002014-07-29T01:13:23+08:00

    Uma maneira de fazer isso - tenha uma coluna varchar com uma lista delimitada de referências adicionais, se existirem (123.458.658.587 etc). Em seguida, crie uma UDF para dividir esses dados, se existirem, que você pode usar em consultas SELECT. Deve ser fácil projetar o UDF para extrair os dados. Como é raro, não deve prejudicar muito os recursos. Uma coluna varchar também deve significar requisitos mínimos de espaço extra.

    • -1

relate perguntas

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

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

  • Como determinar se um Índice é necessário ou necessário

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