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 / 44956
Accepted
Johntron
Johntron
Asked: 2013-06-21 06:18:32 +0800 CST2013-06-21 06:18:32 +0800 CST 2013-06-21 06:18:32 +0800 CST

Boa explicação do comportamento em cascata (ON DELETE/UPDATE)

  • 772

Não crio esquemas todos os dias, mas quando faço isso, tento configurar atualizações/exclusões em cascata corretamente para facilitar a administração. Eu entendo como as cascatas funcionam, mas nunca consigo lembrar qual tabela é qual.

Por exemplo, se eu tiver duas tabelas - Parente Child- com uma chave estrangeira nessas Childreferências Parente tiver ON DELETE CASCADE, quais registros acionam uma cascata e quais registros são excluídos pela cascata? Meu primeiro palpite seria que os Childregistros são excluídos quando Parentos registros são excluídos, já que Childos registros dependem dos Parentregistros, mas o ON DELETEé ambíguo; pode significar excluir o Parentregistro quando o Childregistro for excluído ou pode significar excluir o Childregistro quando o Parentfor excluído. Então qual é?

Eu gostaria que a sintaxe fosse ON PARENT DELETE, CASCADE, ON FOREIGN DELETE, CASCADEou algo semelhante para remover a ambiguidade. Alguém tem algum mnemônico para lembrar disso?

mysql foreign-key
  • 5 5 respostas
  • 280622 Views

5 respostas

  • Voted
  1. Best Answer
    ypercubeᵀᴹ
    2013-06-21T07:00:40+08:002013-06-21T07:00:40+08:00

    Se você gosta dos termos Parente Childe acha que eles são fáceis de serem lembrados, você pode gostar da tradução de ON DELETE CASCADEparaLeave No Orphans!

    O que significa que quando uma Parentlinha é excluída (eliminada), nenhuma linha órfã deve permanecer ativa na Childtabela. Todos os filhos da linha pai também são eliminados (excluídos). Se algum desses filhos tiver netos (em outra tabela por meio de outra chave estrangeira) e lá estiver ON DELETE CASCADEdefinido, eles também devem ser eliminados (e todos os descendentes, desde que haja um efeito cascata definido).

    A FOREIGN KEYprópria restrição também pode ser descrita como Allow No Orphans!(em primeiro lugar). Não Childdeve ser permitido (escrito) na tabela filho se não tiver um Parent(uma linha na tabela pai).

    Para consistência, o ON DELETE RESTRICTpode ser traduzido para o (menos agressivo) You Can't Kill Parents!Somente linhas sem filhos podem ser eliminadas (excluídas).

    • 204
  2. Mike Sherrill 'Cat Recall'
    2013-06-21T06:35:46+08:002013-06-21T06:35:46+08:00

    Por exemplo, se eu tiver duas tabelas - Pai e Filho - onde os registros Filho são de propriedade dos registros Pai, qual tabela precisa do ON DELETE CASCADE?

    ON DELETE CASCADE é uma cláusula opcional em uma declaração de chave estrangeira. Assim vai com a declaração de chave estrangeira. (Significando, na tabela "filho".)

    ...pode significar excluir o registro pai quando o registro filho é excluído ou pode significar excluir o registro filho quando o pai é excluído. Então qual é?

    Uma maneira de interpretar uma declaração de chave estrangeira é: "Todos os valores válidos para esta coluna vêm de 'that_column' em 'that_table'." Quando você exclui uma linha na tabela "filho", ninguém se importa. Não afeta a integridade dos dados.

    Quando você exclui uma linha da tabela "pai" -- de "that_table" -- você remove um valor válido dos valores possíveis para a tabela "filho". Para manter a integridade dos dados, você precisa fazer algo na tabela "filho". Exclusões em cascata é uma coisa que você pode fazer.


    Capítulo e versículo, dos documentos do PostgreSQL .

    Restringir e exclusões em cascata são as duas opções mais comuns. RESTRICT impede a exclusão de uma linha referenciada. NO ACTION significa que, se ainda existirem linhas de referência quando a restrição for verificada, um erro será gerado; este é o comportamento padrão se você não especificar nada. (A diferença essencial entre essas duas opções é que NO ACTION permite que a verificação seja adiada até mais tarde na transação, enquanto RESTRICT não.) CASCADE especifica que quando uma linha referenciada é excluída, a(s) linha(s) que a referencia(m) deve(m) ser excluída(s) automaticamente também. Existem duas outras opções: SET NULL e SET DEFAULT. Isso faz com que as colunas de referência nas linhas de referência sejam definidas como nulas ou seus valores padrão, respectivamente, quando a linha referenciada é excluída. Observe que isso não o isenta de observar quaisquer restrições. Por exemplo, se uma ação especificar SET DEFAULT, mas o valor padrão não satisfizer a restrição de chave estrangeira, a operação falhará.

    • 46
  3. Evan Carroll
    2018-07-26T13:42:15+08:002018-07-26T13:42:15+08:00

    Especificações SQL:2011

    Existem cinco opções para ON DELETEe ON UPDATEque podem ser aplicadas ao FOREIGN KEY. Eles são chamados <referential actions>, diretamente da especificação SQL:2011

    • ON DELETE CASCADE: se uma linha da tabela referenciada for excluída, todas as linhas correspondentes na tabela de referência serão excluídas.
    • ON DELETE SET NULL: se uma linha da tabela referenciada for excluída, todas as colunas de referência em todas as linhas correspondentes da tabela de referência serão definidas como nulas.
    • ON DELETE SET DEFAULT: se uma linha da tabela referenciada for excluída, todas as colunas de referência em todas as linhas correspondentes da tabela de referência serão definidas para o valor padrão da coluna.
    • ON DELETE RESTRICT: é proibido excluir uma linha da tabela referenciada se essa linha tiver alguma linha correspondente na tabela de referência.
    • ON DELETE NO ACTION (o padrão) : não há ação de exclusão referencial; a restrição referencial especifica apenas uma verificação de restrição.

    A chave estrangeira estabelece o relacionamento dependente. O <referential action>determina o que acontece quando o relacionamento é dissolvido.

    Exemplo / Metáfora / Explicação

    Para este exemplo, vamos aceitar o modelo comum de sociedade e economia: onde cada businessuma é uma empresa que mantém um relacionamento com a empresa bourgeoisiepor meio de um fatcat_owner.

    CREATE TABLE bourgeoisie(
      fatcat_owner varchar(100) PRIMARY KEY
    );
    INSERT INTO bourgeoisie(fatcat_owner) VALUES
      ( 'Koch Brothers' );
    
    CREATE TABLE business (
      name         varchar(100),
      fatcat_owner varchar(100) REFERENCES bourgeoisie
    );
    INSERT INTO business(name, fatcat_owner)
      VALUES ('Georgia-Pacific', 'Koch Brothers');
    

    Se todos os businesses são diretamente afetados por bourgeoisieeles fatcat_owner, então o que você faz depois da revolução dos trabalhadores quando você purga os fatcat_ownere tem uma sociedade sem classes?

    -- Viva la revolución 
    BEGIN;
      DELETE FROM bourgeoisie;
    END;
    

    Você tem algumas opções aqui,

    • Pare a revolução. Na linguagem SQL, RESTRICT. Algumas pessoas acreditam que este é o mal menor, mas geralmente estão erradas.

    • Permita que continue. Nesse caso, quando a revolução acontecer, o SQL oferece quatro opções,

      • SET NULL-- deixe em branco. Quem sabe, talvez o capitalismo seja restaurado bourgeoisiee os oligarcas preencham o rol do fatcat_owners. Nota importante, a coluna deve ser NULLABLE(not NOT NULL) ou isso nunca pode acontecer.

      • SET DEFAULT-- talvez você teve um DEFAULTque lidou com isso? A DEFAULTpode chamar uma função. Talvez seu esquema já esteja pronto para a revolução.

      • CASCADE-- não há controle de danos. Se o bourgeoisievai, o mesmo acontece com o business. Se uma empresa deve ter um fatcat_owner, às vezes faz mais sentido perder os dados em vez de ter uma não empresa em uma businesstabela.

      • NO ACTION-- este é essencialmente um método de atrasar a verificação, no MySQL não é diferente de RESTRICT, mas no PostgreSQL, você poderia fazer

            -- Not a real revolution.
            -- requires constraint be DEFERRABLE INITIALLY DEFERRED
            BEGIN;
              SET CONSTRAINTS ALL DEFERRED;
              DELETE FROM bourgeoisie;
              INSERT INTO bourgeoisie VALUES ( 'Putin' );
              UPDATE business SET fatcat_owner = 'Putin';
            END;
        

        Em tal sistema, a restrição é validada somente antes que a transação seja confirmada. Isso pode resultar na interrupção da revolução, mas você pode se recuperar na transação - para algum grau de "recuperação".

    • 16
  4. msouth
    2019-05-29T08:45:48+08:002019-05-29T08:45:48+08:00

    Um simples mnemônico seria

    ON DELETE do pai CASCADE [por exclusão] aqui

    Isso informa quais exclusões (exclusões do pai) são cascateadas, para onde vai a instrução ON DELETE CASCADE (no filho) e o que é excluído (o filho).

    • 4
  5. George Mogilevsky
    2018-07-20T21:59:25+08:002018-07-20T21:59:25+08:00

    bem, talvez possamos racionalizar a sintaxe. Vamos dar um exemplo em Python:

    class Parent(self):
        # define parent's fields
    
    class Child(self):    
        # define child's fields
        parent_pk_is_childs_foreign_key = models.ForeignKey(Parent, on_delete=models.CASCADE)
    

    o que esta linha diz é on_delete do Pai (que é acidentalmente mencionado na declaração), por favor, desfaça a exclusão no filho. É por isso que a instrução CASCADE é definida no nível filho, marca os filhos que precisam ser excluídos

    Por exemplo, se você tivesse outra classe

    class GrownUpChild(self):    
            # define grown up child's fields
            parent_pk_is_childs_foreign_key = models.ForeignKey(Parent, on_delete=models.DO_NOTHING)
    

    essa estrutura mostraria claramente quais das crianças precisam ser removidas (Child) e quais devem ficar (GrownUpChild), embora órfãs

    [Editar: Dado o contexto da discussão, especificamente em casos de on_delete=models.CASCADE etc,] na verdade, muitas vezes é um comportamento desejado deixar filhos de um pai excluído, devido a razões de auditoria e relatórios, bem como a recuperação acidental exclusões. [é claro que o software de nível empresarial será construído em torno desse comportamento e sinalizará os registros excluídos como excluídos=1 em vez de realmente excluí-los e também não os incluirá em nenhuma consulta para o front-end, menos alguns relatórios especialmente projetados. Além disso, ele terá a função de limpar os registros excluídos==1 do banco de dados, que normalmente serão executados pelo administrador da interface do usuário, muitas vezes evitando qualquer envolvimento do lado do administrador do banco de dados.]

    • -3

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • 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

    Conceder acesso a todas as tabelas para um usuário

    • 5 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
    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
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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