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 / 80951
Accepted
AlwaysLearningNewStuff
AlwaysLearningNewStuff
Asked: 2014-10-24 08:13:57 +0800 CST2014-10-24 08:13:57 +0800 CST 2014-10-24 08:13:57 +0800 CST

Não sei como transformar entidade variável em tabela relacional

  • 772

INTRODUÇÃO E INFORMAÇÕES RELEVANTES:

O exemplo a seguir ilustra o problema que enfrento:

O animal tem uma raça, que pode ser um gato ou um cachorro . O gato pode ser siamês ou persa . O cão pode ser um pastor alemão ou um labrador retriver .

Animal é uma entidade forte, enquanto sua raça é um atributo que pode ter um dos dois valores oferecidos ( gato ou cachorro ). Ambos os valores são complexos (adicionei aqui apenas o tipo de cachorro/gato para ilustrar o problema, mas também pode haver o nome do gato/cachorro e um monte de outras coisas).

PROBLEMA:

Não sei como criar tabelas relacionais para este exemplo.

MEUS ESFORÇOS PARA RESOLVER O PROBLEMA:

Tentei desenhar o diagrama ER, usando a notação de Chen, que representa o problema, mas sendo iniciante não sei se fiz certo. Aqui está o que eu tenho:

insira a descrição da imagem aqui

Peço desculpas se desenhei algo errado, por favor me corrija se for o caso. Não desejo simplesmente obter "solução gratuita", mas também aprender como lidar com esse problema para que eu possa resolvê-lo sozinho no futuro.

A única coisa que me vem à cabeça é criar duas mesas separadas, uma para gatos e outra para cachorros. Além disso, o atributo raça na tabela Animal armazenaria apenas um valor de gato ou cachorro . Algo assim:

Animal< # Animal_ID, race, other attributes >
Cat < # Cat_ID, $ Animal_ID, breed >
Dog < # Dog_ID, $ Animal_ID, breed >

Eu realmente tenho um mau pressentimento sobre minha solução e temo que esteja errada, daí a pergunta abaixo.

PERGUNTAS:

  • Como posso transformar meu exemplo em diagrama ER?
  • Como transformar esse diagrama ER em tabelas relacionais?

Se mais informações forem necessárias, deixe um comentário e atualizarei minha postagem o mais rápido possível. Também sinta-se à vontade para adicionar tags apropriadas, pois sou relativamente novo aqui.

Obrigada.

database-design subtypes
  • 4 4 respostas
  • 1957 Views

4 respostas

  • Voted
  1. Best Answer
    Solomon Rutzky
    2014-10-27T11:44:03+08:002014-10-27T11:44:03+08:00

    A estrutura adequada para este cenário é um modelo de subclasse/herança e é quase idêntica ao conceito que propus nesta resposta: lista ordenada heterogênea de valores .

    O modelo proposto nesta questão é, na verdade, bastante próximo, pois a Animalentidade contém o tipo (ou seja, race) e as propriedades comuns a todos os tipos. No entanto, há duas pequenas alterações que são necessárias:

    1. Remova os campos Cat_ID e Dog_ID de suas respectivas entidades:

      O conceito-chave aqui é que tudo é um Animal, independentemente de race: Cat, Dog, Elephante assim por diante. Dado esse ponto de partida, qualquer particular não precisa realmente de um identificador separado, pois race:Animal

      1. o Animal_IDé único
      2. o Cat, Dog, e quaisquer raceentidades adicionais adicionadas no futuro não representam, por si só, totalmente qualquer Animal; eles só têm significado quando usados ​​em combinação com as informações contidas na entidade-mãe, Animal.

      Portanto, a Animal_IDpropriedade nas entidades Cat, Dog, etc é a PK e a FK de volta à Animalentidade.

    2. Diferencie os tipos de breed:

      Só porque duas propriedades compartilham o mesmo nome não significa necessariamente que essas propriedades são as mesmas, mesmo que o nome seja o mesmo implique tal relacionamento. CatBreedNeste caso, o que você realmente tem são DogBreed"tipos" separados

    Notas Iniciais

    1. O SQL é específico para o Microsoft SQL Server (ou seja, é T-SQL). Ou seja, tenha cuidado com os tipos de dados, pois eles não são os mesmos em todos os RDBMSs. Por exemplo, estou usando, VARCHARmas se você precisar armazenar qualquer coisa fora do conjunto ASCII padrão, você realmente deve usar NVARCHAR.
    2. Os campos de ID das tabelas "type" ( Race, CatBreed, e DogBreed) não são incrementados automaticamente (ou seja, IDENTITY em termos de T-SQL) porque são constantes do aplicativo (ou seja, fazem parte do aplicativo) que são valores de pesquisa estáticos no banco de dados e são representados como enums em C# (ou outras linguagens). Se valores forem adicionados, eles serão adicionados em situações controladas. Eu reservo o uso de campos de auto-incremento para dados do usuário que chegam através do aplicativo.
    3. A convenção de nomenclatura que uso é nomear cada tabela de subclasse começando com o nome da classe principal seguido pelo nome da subclasse. Isso ajuda a organizar as tabelas, bem como indica claramente (sem olhar para os FKs) o relacionamento da tabela da subclasse com a tabela da entidade principal.
    4. Consulte a seção "Edição final" no final para obter uma observação sobre as visualizações.

    "Raça" como "Raça" - Abordagem Específica

    Raça como diagrama específico da raça
    Este primeiro conjunto de tabelas são as tabelas de pesquisa/tipos:

    CREATE TABLE Race
    (
      RaceID INT NOT NULL PRIMARY KEY
      RaceName VARCHAR(50) NOT NULL
    );
    
    CREATE TABLE CatBreed
    (
      CatBreedID INT NOT NULL PRIMARY KEY,
      BreedName VARCHAR(50),
      CatBreedAttribute1 INT,
      CatBreedAttribute2 VARCHAR(10)
      -- other "CatBreed"-specific properties as needed
    );
    
    CREATE TABLE DogBreed
    (
      DogBreedID INT NOT NULL PRIMARY KEY,
      BreedName VARCHAR(50),
      DogBreedAttribute1 TINYINT
      -- other "DogBreed"-specific properties as needed
    );
    

    Esta segunda listagem é a principal entidade "Animal":

    CREATE TABLE Animal
    (
      AnimalID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
      RaceID INT NOT NULL, -- FK to Race
      Name VARCHAR(50)
      -- other "Animal" properties that are shared across "Race" types
    );
    
    ALTER TABLE Animal
      ADD CONSTRAINT [FK_Animal_Race]
      FOREIGN KEY (RaceID)
      REFERENCES Race (RaceID);
    

    Este terceiro conjunto de tabelas são as entidades de subclasse complementares que completam a definição de cada uma Racedas seguintes Animal:

    CREATE TABLE AnimalCat
    (
      AnimalID INT NOT NULL PRIMARY KEY, -- FK to Animal
      CatBreedID INT NOT NULL, -- FK to CatBreed
      HairColor VARCHAR(50) NOT NULL
      -- other "Cat"-specific properties as needed
    );
    
    ALTER TABLE AnimalCat
      ADD CONSTRAINT [FK_AnimalCat_CatBreed]
      FOREIGN KEY (CatBreedID)
      REFERENCES CatBreed (CatBreedID);
    
    ALTER TABLE AnimalCat
      ADD CONSTRAINT [FK_AnimalCat_Animal]
      FOREIGN KEY (AnimalID)
      REFERENCES Animal (AnimalID);
    
    
    CREATE TABLE AnimalDog
    (
      AnimalID INT NOT NULL PRIMARY KEY, -- FK to Animal
      DogBreedID INT NOT NULL, -- FK to DogBreed
      HairColor VARCHAR(50) NOT NULL
      -- other "Dog"-specific properties as needed
    );
    
    ALTER TABLE AnimalDog
      ADD CONSTRAINT [FK_AnimalDog_DogBreed]
      FOREIGN KEY (DogBreedID)
      REFERENCES DogBreed (DogBreedID);
    
    ALTER TABLE AnimalDog
      ADD CONSTRAINT [FK_AnimalDog_Animal]
      FOREIGN KEY (AnimalID)
      REFERENCES Animal (AnimalID);
    

    O modelo que usa um tipo compartilhado breedé mostrado após a seção "Notas adicionais".

    Notas Adicionais

    1. O conceito de breedparece ser um ponto focal para confusão. Foi sugerido por jcolebrand (em um comentário sobre a pergunta) que breedé uma propriedade compartilhada entre os diferentes races, e as outras duas respostas a integram como tal em seus modelos. Isso é um erro, no entanto, porque os valores de breednão são compartilhados entre os diferentes valores de race. Sim, estou ciente de que os outros dois modelos propostos tentam resolver esse problema criando raceum pai de breed. Embora isso resolva tecnicamente o problema de relacionamento, não ajuda a resolver a questão geral de modelagem sobre o que fazer com propriedades não comuns, nem como lidar com um raceque não possui um breed. Mas, no caso de tal propriedade ter a garantia de existir em todos osAnimals, incluirei uma opção para isso também (abaixo).
    2. Os modelos propostos por vijayp e DavidN (que parecem idênticos) não funcionam porque:
      1. Eles também
        1. não permitem que propriedades não comuns sejam armazenadas (pelo menos não para instâncias individuais de qualquer Animal), ou
        2. exigem que todas as propriedades de todos os races sejam armazenadas na Animalentidade, que é uma maneira muito plana (e quase não relacional) de representar esses dados. Sim, as pessoas fazem isso o tempo todo, mas significa ter muitos campos NULL por linha para as propriedades que não são destinadas a esse determinado raceE saber quais campos por linha estão associados ao particular racedesse registro.
      2. Eles não permitem adicionar um raceof Animalno futuro que não tenha breedcomo propriedade. E mesmo que ALL Animals tenha um breed, isso não mudaria a estrutura devido ao que foi observado anteriormente breed: isso breeddepende de the race(ou seja, breedfor Catnão é a mesma coisa que breedfor Dog).

    "Raça" como abordagem de propriedade comum/compartilhada

    insira a descrição da imagem aqui
    Observe:

    1. O SQL abaixo pode ser executado no mesmo banco de dados do modelo apresentado acima:

      1. a Racemesa é a mesma
      2. a Breedmesa é nova
      3. As três Animaltabelas foram anexadas com um2
    2. Even with Breed being a now common property, it does not seem right not to have Race noted in the main/parent entity (even if it is technically relationally correct). So, both RaceID and BreedID are represented in Animal2. In order to prevent a mismatch between the RaceID noted in Animal2 and a BreedID that is for a different RaceID, I have added a FK on both RaceID, BreedID that references a UNIQUE CONSTRAINT of those fields in the Breed table. I usually despise pointing a FK to a UNIQUE CONSTRAINT, but here is one of the few valid reasons to do so. A UNIQUE CONSTRAINT is logically an "Alternate Key", which makes it valid for this use. Please also note that the Breed table still has a PK on just BreedID.
      1. The reason for not going with just a PK on the combined fields and no UNIQUE CONSTRAINT is that it would allow for the same BreedID to be repeated across different values of RaceID.
      2. The reason for not switching which the PK and UNIQUE CONSTRAINT around is that this might not be the only usage of BreedID, so it should still be possible to reference a specific value of Breed without having the RaceID available.
    3. While the following model does work, it has two potential flaws regarding the concept of a shared Breed (and are why I prefer the Race-specific Breed tables).
      1. There is an implicit assumption that ALL values of Breed have the same properties. There is no easy way in this model to have disparate properties between Dog "breeds" and Elephant "breeds". However, there still is a way to do this, which is noted in the "Final Edit" section.
      2. There is no way to share a Breed across more than one race. I am not sure if that is desirable to do (or maybe not in the concept of animals but possibly in other situations that would be using this type of model), but it is not possible here.
    CREATE TABLE Race
    (
      RaceID INT NOT NULL PRIMARY KEY,
      RaceName VARCHAR(50) NOT NULL
    );
    
    CREATE TABLE Breed
    (
      BreedID INT NOT NULL PRIMARY KEY,
      RaceID INT NOT NULL, -- FK to Race
      BreedName VARCHAR(50)
    );
    
    ALTER TABLE Breed
      ADD CONSTRAINT [UQ_Breed]
      UNIQUE (RaceID, BreedID);
    
    ALTER TABLE Breed
      ADD CONSTRAINT [FK_Breed_Race]
      FOREIGN KEY (RaceID)
      REFERENCES Race (RaceID);
    
    CREATE TABLE Animal2
    (
      AnimalID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
      RaceID INT NOT NULL, -- FK to Race, FK to Breed
      BreedID INT NOT NULL, -- FK to Breed
      Name VARCHAR(50)
      -- other properties common to all "Animal" types
    );
    
    ALTER TABLE Animal2
      ADD CONSTRAINT [FK_Animal2_Race]
      FOREIGN KEY (RaceID)
      REFERENCES Race (RaceID);
    
    -- This FK points to the UNIQUE CONSTRAINT on Breed, _not_ to the PK!
    ALTER TABLE Animal2
      ADD CONSTRAINT [FK_Animal2_Breed]
      FOREIGN KEY (RaceID, BreedID)
      REFERENCES Breed (RaceID, BreedID);
    
    
    CREATE TABLE AnimalCat2
    (
      AnimalID INT NOT NULL PRIMARY KEY, -- FK to Animal
      HairColor VARCHAR(50) NOT NULL
    );
    
    ALTER TABLE AnimalCat2
      ADD CONSTRAINT [FK_AnimalCat2_Animal2]
      FOREIGN KEY (AnimalID)
      REFERENCES Animal2 (AnimalID);
    
    CREATE TABLE AnimalDog2
    (
      AnimalID INT NOT NULL PRIMARY KEY,
      HairColor VARCHAR(50) NOT NULL
    );
    
    ALTER TABLE AnimalDog2
      ADD CONSTRAINT [FK_AnimalDog2_Animal2]
      FOREIGN KEY (AnimalID)
      REFERENCES Animal2 (AnimalID);
    


    Final Edit (hopefully ;-)

    1. Regarding the possibility (and then difficulty) of handling disparate properties between types of Breed, it is possible to employ the same subclass / inheritance concept but with Breed as the main entity. In this setup the Breed table would have the properties common to all types of Breed (just like the Animal table) and RaceID would represent the type of Breed (same as it does in the Animal table). Then you would have subclass tables such as BreedCat, BreedDog, and so on. For smaller projects this might be considered "over-engineering", but it is being mentioned as an option for situations that would benefit from it.
    2. For both approaches, it sometimes helps to create Views as short-cuts to the full entities. For example, consider:

      CREATE VIEW Cats AS
         SELECT  an.AnimalID,
                 an.RaceID,
                 an.Name,
                 -- other "Animal" properties that are shared across "Race" types
                 cat.CatBreedID,
                 cat.HairColor
                 -- other "Cat"-specific properties as needed
         FROM    Animal an
         INNER JOIN  AnimalCat cat
                 ON  cat.AnimalID = an.AnimalID
         -- maybe add in JOIN(s) and field(s) for "Race" and/or "Breed"
      
    3. While not part of the logical entities, it is fairly common to have audit fields in the tables to at least get a sense of when the records are being inserted and updated. So in practical terms:
      1. A CreatedDate field would be added to the Animal table. This field is not needed in any of the subclass tables (e.g. AnimalCat) as the rows being inserted for both tables should be done at the same time within a transaction.
      2. A LastModifiedDate field would be added to the Animal table and all subclass tables. This field gets updated only if that particular table is updated: if an update occurs in AnimalCat but not in Animal for a particular AnimalID, then only the LastModifiedDate field in AnimalCat would be set.
    • 11
  2. Walter Mitty
    2014-10-28T03:18:01+08:002014-10-28T03:18:01+08:00

    First off, you are doing well to distinguish between ER modeling and relational modeling. Many newbies don't.

    Here are some buzzwords you can use to look up helpful articles on the web.

    Your case is a classic case of class/subclass or, if you like, type/subtype.

    The phrase that's used in ER modeling is "generalization/specialization". And many of the articles show this under something called EER (Enhanced Entity-Relationship) modeling. This wasn't in Peter Chen's original presentation of ER modeling. It was added later. For a pretty good summary of gen/spec in pdf form, click here

    Next, when converting a class/subclass case to relational modeling you design tables. There is more than one approach. The two main approaches are called single table inheritance and class table inheritance. Each has advantages and drawbacks. The best presentation of these two designs comes from Martin Fowler. You can see his outline here and here.

    The big advantage of single table inheritance is simplicity. It's all stored in one table. The big drawback is a lot of NULLS. This can waste space and time and result in confusing logic.

    A herança da tabela de classes requer junções, mas elas são simples e rápidas. Especialmente se você usar uma técnica chamada chave primária compartilhada, na qual o PK nas tabelas da subclasse é uma cópia do PK na tabela da superclasse. Você pode criar exibições para cada subclasse que une dados de superclasse com dados de subclasse.

    Finalmente, há uma tag nesta área que reúne perguntas como a sua.
    Aqui está: subtipos

    • 4
  3. vijayp
    2014-10-26T22:24:56+08:002014-10-26T22:24:56+08:00

    Eu vejo no design possível como

    MesaRace

    RaceId- PK- Int
    RaceName - Varchar(50)
    

    MesaBreed

    BreedId - PK- Int
    RaceId - FK - Int
    BreedName - varchar(50)
    

    MesaAnimal

    AnimalId - PK- Int
    BreedId - FK - Int
    Other Columns....
    

    Esses PKs acima seriam colunas de incremento automático. Outras colunas na Animaltabela podem ser nomeadas de acordo.

    insira a descrição da imagem aqui

    • 3
  4. DavidN
    2014-10-25T11:16:32+08:002014-10-25T11:16:32+08:00

    Seu método atual não é ruim. No entanto, se você adicionar mais raças posteriormente (pássaro, peixe, etc.), criar uma tabela separada para cada uma pode ser complicado. Eu recomendaria algo como o seguinte:

    Animal < # Animal_ID, Breed_ID, other attributes >
    Breed < # Breed_ID, Race_ID >
    Race < # Race_ID >
    

    Uma raça, no meu entendimento, deveria ter apenas uma raça. Portanto, se você armazenar a raça na tabela Animal, poderá determinar a raça juntando-se à tabela Raça. Obviamente, adicione quaisquer outros atributos (nome, descrição, etc.) às tabelas de raças e raças conforme necessário.

    • 0

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