Nano Hash - криптовалюты, майнинг, программирование

Как смоделировать это отношение множественного наследования с помощью СУБД?

Я смотрю на эту модель данных, которую придумал, и не чувствую себя комфортно. Я изменил имена сущностей, чтобы они (надеюсь) имели больше смысла. В любом случае, как бы вы смоделировали следующее?

У меня есть 3 сущности. ПравительствоЗаказчик, ЧастныйЗаказчик, ОбщественныйЗаказчик. Частный и Государственный Клиенты являются Корпоративными Клиентами. Корпоративные и государственные клиенты — это учетные записи. Все учетные записи имеют одно и то же ключевое пространство (поэтому, если PrivateCustomer имеет PK, равный 1, у Public или GovernmentCustomer не должно быть возможности иметь PK, равный 1). Корпоративные клиенты имеют некоторые отношения 1:M, которых нет у государственных клиентов. У PublicCustomers есть некоторые отношения 1:M, которых нет у PrivateCustomers.

Наследие:

Account
  CorporateCustomer
    PrivateCustomer
    PublicCustomer
  GovernmentCustomer

Сейчас моя модель имеет 5 таблиц. Таблица «Учетная запись» является корнем этой иерархии, при этом PK каждой дочерней таблицы является FK для PK ее родителя. Таким образом, все таблицы имеют одинаковый ПК.

Итак, как бы вы смоделировали это? Надеюсь, здесь ничего не пошло не так :).

РЕДАКТИРОВАТЬ:

Также: - Я бы хотел, чтобы БД заботилась о целостности ссылок, а не о приложении. - Корпоративный клиент не может существовать, не будучи ни частным, ни государственным заказчиком. Его аннотация.


Ответы:


1

Один путь может быть:

ACCOUNTS -> ACCOUNT_CUSTOMERS <- CUSTOMERS

У CUSTOMERS должен быть столбец CUSTOMER_TYPE типа Corporate(C), Private(P), Public(Z), Government(G). Поскольку все публичные и частные клиенты также являются корпоративными, если вам нужно получить всех корпоративных клиентов, вы можете сделать что-то вроде:

SELECT *
  FROM ACCOUNTS
     , ACCOUNT_CUSTOMERS
     , CUSTOMERS
 WHERE ACCOUNTS.ID = ACCOUNT_CUSTOMERS.ACCT_ID
   AND CUSTOMERS.ID = ACCOUNT_CUSTOMERS.CUST_ID
   AND CUSTOMERS.CUSTOMER_TYPE in ('C','P','Z')

Я использовал синтаксис ORACLE, но думаю, вы поняли идею.

In response to your edit:

Похоже, у вас всего два типа КЛИЕНТОВ. Корпоративный и государственный. Тогда это еще проще. Я бы использовал логический индикатор для CUSTOMERS, называемый PUBLIC_IND, который, когда false является частным, или другой тип, например ENTITY_TYPE, который может быть Private (P), Public (Z) или None (N). Затем, если вы хотите, чтобы все общедоступные пользователи корпоративных клиентов:

SELECT *
      FROM ACCOUNTS
         , ACCOUNT_CUSTOMERS
         , CUSTOMERS
     WHERE ACCOUNTS.ID = ACCOUNT_CUSTOMERS.ACCT_ID
       AND CUSTOMERS.ID = ACCOUNT_CUSTOMERS.CUST_ID
       AND CUSTOMERS.CUSTOMER_TYPE in ('C')
       AND CUSTOMERS.ENTITY_TYPE = 'Z'
19.06.2009
  • Если я правильно понимаю этот подход, корпоративные клиенты рассматриваются как отдельные лица от государственных и частных клиентов. Я обновил вопрос, чтобы прояснить это. Корпоративные клиенты не могут существовать, не будучи частными или государственными заказчиками. Может ли этот подход работать в этом случае? По сути, я не уверен, когда у меня когда-либо будет запись с буквой «Z» для этого типа. 19.06.2009

  • 2

    Прежде чем вы решите поместить каждый класс в одну таблицу, я бы посмотрел на отношения, в которые они вовлечены, а не на атрибуты. Тривиально оставить некоторые поля нулевыми, если тип записи «X», но невероятно громоздко пытаться установить отношения, которые применяются только к определенным записям в таблице.

    Если отношения классов с другими сущностями точно такие же, то вы можете поместить их все в одну таблицу без каких-либо существенных недостатков.

    28.04.2011

    3

    Я думаю, у вас должны быть только таблицы Account и Customer, а также таблица CustomerRelationship. Различные типы клиентов можно различать с помощью определенного кода типа, а отношения можно поддерживать с помощью таблицы CustomerRelationship.

    19.06.2009

    4

    я согласен с другими, что поля customerType должно быть достаточно, если разные типы клиентов похожи.

    при этом, возможно, только корпоративные клиенты используют одну таблицу, но государственные клиенты достаточно разные, поэтому их необходимо определить в своей собственной таблице. в случае, если это оправдано, одна из схем, которая поможет вам применить ограничение PK, будет состоять в том, чтобы иметь таблицу MasterAccount, которая будет ссылаться на всех клиентов по идентификатору (ограничение PK) и иметь ссылку на их тип на следующем уровне. иерархия (корпоративная или государственная).

    вам все еще нужно отобразить отношения 1-*, что вы могли бы сделать с еще двумя таблицами — таблицей отношений и таблицей сопоставления отношений учетных записей.

    19.06.2009
  • Так что у меня было бы 3 таблицы. MasterAccount (ID, CustomerType), CorporateCustomer (Id - FK на MA) и GovernmentCustomer (ID - FK на MA)? 19.06.2009
  • я предполагаю, что это не упростило бы различение между общедоступным и частным при запросе только таблицы CorporateCustomer. было бы лучше, если бы главная таблица различала corp и gov, а таблица corp различала pub и priv. независимо от того, как вы его нарезаете, если вы не можете хранить все учетные записи в одной таблице, применение уникальных идентификаторов для таблиц становится сложным. 19.06.2009

  • 5

    Если нет существенной разницы в атрибутах, которые отслеживаются между различными типами клиентов, у меня будет только одна таблица с именем Account с некоторым полем CustomerType. вы можете выразить связь 1:m с помощью подробных таблиц, имеющих FK для AccountID.

    Изменить: современные базы данных могут добавлять правила целостности данных помимо ссылочной целостности FK. Например, в SQL Server можно добавить CHECK Constraints, чтобы быть GovernmentCustomer для определенного мастера таблицы деталей. Это может выглядеть примерно так:

    CREATE FUNCTION EnforceGovernmentCustomer(@AccountID int)
    RETURNS bit
    AS 
    BEGIN
       DECLARE @retval bit
       SELECT @retval = 0
       SELECT @retval = 1
       FROM Account
       WHERE AccountID = @AccountID AND AccountType = 3
    
       RETURN @retval
    END;
    GO
    ALTER TABLE GovernmentCustomerDetail
    ADD CONSTRAINT chkGovernmentCustomer CHECK (dbo.EnforceGovernmentCustomer(AccountID) = 1);
    GO
    
    19.06.2009
  • Если я правильно понимаю этот подход, моему приложению придется немного управлять целостностью данных. Например, учетная запись с типом GovernmentCustomer может иметь много финансовых отчетов. Только корпоративные клиенты должны иметь такие отношения. Я прав? Я обновил вопрос, чтобы сделать целостность ссылки более ясной. 19.06.2009
  • @ eed3si9n Спасибо! Мне нужно посмотреть, смогу ли я смоделировать это с учетом пользовательского ограничения проверки. То есть вы вообще против того, чтобы 5 столов разделяли идею ПК? 20.06.2009
  • @TheDeeno, если у вас нет существенно отличающейся информации, которую вы отслеживаете для разных типов, я не вижу необходимости их разделять. РСУБД отслеживает объекты и их отношения, как следует из названия. OO пытается точно отобразить реальный мир, а также вводит поведение, привязанное к данным. Я не вижу преимущества в том, чтобы втиснуть это в БД в этом конкретном сценарии. 20.06.2009

  • 6

    Я знаю, что этот вопрос очень старый, но, поскольку на него еще нет принятого ответа, у меня есть пара идей.

    Одна из возможностей — использовать возможности ORDBMS, другими словами, использовать наследование таблиц. В PostgreSQL вы можете смоделировать это следующим образом:

    (См. документацию о наследовании PostgresSQL http://www.postgresql.org/docs/9.3/static/ddl-inherit.html)

    CREATE TABLE account
    (
       account_id INT,
       PRIMARY KEY(account_id)
    );
    
    CREATE TABLE corporate_customer
    (
       company_name VARCHAR(32),
       country_code CHAR(2),
       PRIMARY KEY(company_name)
    ) INHERITS(account);
    
    CREATE TABLE private_corp_customer
    (
       private_comp_id INT,
       company_owner VARCHAR(32),
       PRIMARY KEY(private_comp_int)
    ) INHERITS(corporate_customer);
    
    CREATE TABLE public_corp_customer
    (
       stock_ticker VARCHAR(6),
       PRIMARY KEY(stock_ticker)
    ) INHERITS(corporate_customer);
    
    CREATE TABLE government_customer
    (
       dept_nbr INT,
       country CHAR(2),
       PRIMARY KEY(dept_nbr)
    ) INHERITS(account);
    

    Различные поставщики СУБД реализуют это по-разному. В PostgresSQL есть несколько важных предостережений, описанных здесь:

    http://ledgersmbdev.blogspot.com/2012/08/postgresql-or-modelling-part-3-table.html

    В частности, обратите внимание на часть о том, что первичные и внешние ключи не наследуются.

    Если вам не нравятся ограничения вашей СУБД или вы используете СУБД, не имеющую объектно-реляционных функций, то другой вариант — использовать альтернативу, предложенную в статье выше, и использовать вторичные ключи. Это будет смоделировано так:

    CREATE TABLE account
    (
       account_id INT,
       account_type INT NOT NULL,
       PRIMARY KEY(account_id),
       UNIQUE (account_id, account_type)
    );
    
    CREATE TABLE corporate_customer
    (
       account_id INT,
       account_type INT NOT NULL CHECK(account_type IN (1,2)),
       company_name VARCHAR(32),
       country_code CHAR(2),
       PRIMARY KEY(account_id, account_type),
       FOREIGN KEY(account_id, account_type) REFERENCES account(account_id, account_type),
       UNIQUE(account_id, account_type, company_name)
    );
    
    CREATE TABLE private_corp_customer
    (
       account_id INT,
       account_type INT NOT NULL CHECK(account_type = 1),
       company_name VARCHAR(32),
       company_owner VARCHAR(32),
       PRIMARY KEY(account_id, account_type, company_name),
       FOREIGN KEY(account_id, account_type, company_name) REFERENCES corporate_customer (account_id, account_type, company_name)
    );
    
    CREATE TABLE public_corp_customer
    (
       account_id INT,
       account_type INT NOT NULL CHECK (account_type = 2),
       company_name VARCHAR(32),
       stock_ticker CHAR(6),
       PRIMARY KEY(account_id, account_type, company_name),
       FOREIGN KEY(account_id, account_type, company_name) 
       REFERENCES corporate_customer (account_id, account_type, company_name)
    ) INHERITS(corporate_customer);
    
    CREATE TABLE government_customer
    (
       account_id INT,
       account_type INT NOT NULL CHECK(account_type = 3),
       dept_nbr INT,
       country_code CHAR(2),
       PRIMARY KEY(account_id, account_type),
       FOREIGN KEY(account_id, account_type) REFERENCES account(account_id, account_type),
       UNIQUE(account_id, account_type, dept_nbr)
     );
    

    Приведенный выше дизайн также имеет некоторые важные ограничения (которые также описаны в статье выше). Во-первых, хотя не должно быть возможности иметь учетную запись, которая не является частной, государственной или государственной, это возможно; у вас могут быть только учетные записи, корпоративные учетные записи, которые не являются ни публичными, ни частными... поддерживать их становится кошмаром. Ограничения CHECK также могут снизить производительность, и вы заметите как дублирование данных в дочерних объектах, так и отсутствие информации в корпоративных дочерних объектах (country_code).

    Какие ограничения вы выберете, будет зависеть от вашего поставщика СУБД и от того, с какой головной болью вы хотите справиться.

    20.07.2014
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..