Что-то вроде наследования в дизайне базы данных

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

25
задан Eric Lavoie 18 June 2014 в 14:46
поделиться

6 ответов

type и id_in_type дизайн называют Полиморфные Ассоциации . Этот дизайн нарушает правила нормализации несколькими способами. Если ничто иное, это должен быть красный флаг, что Вы не можете объявлять реальное ограничение внешнего ключа, потому что эти id_in_type может сослаться на любую из нескольких таблиц.

Вот лучший способ определить Ваши таблицы:

  • Делают абстрактную таблицу Vehicles для обеспечения абстрактной контрольной точки для всех подтипов механизма и тестов механизма.
  • Каждый подтип механизма имеет первичный ключ, который не делает автоинкремента, но вместо этого ссылок Vehicles.
  • Каждый тестовый подтип имеет первичный ключ, который не делает автоинкремента, но вместо этого ссылок Tests.
  • Каждый тестовый подтип также имеет внешний ключ к соответствующему подтипу механизма.

Вот демонстрационный DDL:

CREATE TABLE Vehicles (
 vehicle_id INT AUTO_INCREMENT PRIMARY KEY
);

CREATE TABLE Speedboats (
 vehicle_id INT PRIMARY KEY,
 col_about_speedboats_but_not_tests1 INT,
 col_about_speedboats_but_not_tests2 INT,
 FOREIGN KEY(vehicle_id) REFERENCES Vehicles(vehicle_id)
);

CREATE TABLE Cars (
 vehicle_id INT PRIMARY KEY,
 col_about_cars_but_not_tests1 INT,
 col_about_cars_but_not_tests2 INT,
 FOREIGN KEY(vehicle_id) REFERENCES Vehicles(vehicle_id)
);

CREATE TABLE Gokarts (
 vehicle_id INT PRIMARY KEY,
 col_about_gokarts_but_not_tests1 INT,
 col_about_gokarts_but_not_tests2 INT,
 FOREIGN KEY(vehicle_id) REFERENCES Vehicles(vehicle_id)
);

CREATE TABLE Tests (
 test_id INT AUTO_INCREMENT PRIMARY KEY,
 col_about_all_tests1 INT,
 col_about_all_tests2 INT
);

CREATE TABLE SpeedboatTests (
 test_id INT PRIMARY KEY,
 vehicle_id INT NOT NULL,
 col_about_speedboat_tests1 INT,
 col_about_speedboat_tests2 INT,
 FOREIGN KEY(test_id) REFERENCES Tests(test_id),
 FOREIGN KEY(vehicle_id) REFERENCES Speedboats(vehicle_id)
);

CREATE TABLE CarTests (
 test_id INT PRIMARY KEY,
 vehicle_id INT NOT NULL,
 col_about_car_tests1 INT,
 col_about_car_tests2 INT,
 FOREIGN KEY(test_id) REFERENCES Tests(test_id),
 FOREIGN KEY(vehicle_id) REFERENCES Cars(vehicle_id)
);

CREATE TABLE GokartTests (
 test_id INT PRIMARY KEY,
 vehicle_id INT NOT NULL,
 col_about_gokart_tests1 INT,
 col_about_gokart_tests2 INT,
 FOREIGN KEY(test_id) REFERENCES Tests(test_id),
 FOREIGN KEY(vehicle_id) REFERENCES Gokarts(vehicle_id)
);

Вы могли альтернативно объявить Tests.vehicle_id, какие ссылки Vehicles.vehicle_id и избавляются от vehicle_id внешних ключей в каждой тестовой таблице подтипа, но это разрешило бы аномалии, такие как тест быстроходного катера, который ссылается на идентификатор gokart.

39
ответ дан Bill Karwin 19 June 2014 в 01:46
поделиться

Я расстался бы, это в различные таблицы, например, Механизм (идентификатор, введите, и т.д.) VehicleAttributes () VehicleID, AttributeID, Значение), CrashTestInfo (VehicleID, CrashtestID, Дата и т.д.) CrashtestAttributes (CrashTestID, AttributeID, Значение)

Или а не атрибуты, отдельные таблицы для каждого набора подобной детали, которая должна быть зарегистрирована.

0
ответ дан cjk 19 June 2014 в 01:46
поделиться

Если Вы используете SQLAlchemy, объектно-реляционный картопостроитель для Python, Вы можете настраивать, как иерархии наследования отображаются на таблицах базы данных . Объектно-реляционные картопостроители хороши для приручения в других отношениях утомительного SQL.

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

0
ответ дан joeforker 19 June 2014 в 01:46
поделиться
  • 1
    Можно также поместить перечисления в пространства имен тогда как макросы can' t быть. – Greg Rogers 26 September 2008 в 14:48

Для отображения иерархий наследования к таблицам базы данных я думаю, что Martin Fowler размечает альтернативы довольно хорошо в его книге Шаблоны Архитектуры приложений для предприятия.

http://martinfowler.com/eaaCatalog/singleTableInheritance.html

http://martinfowler.com/eaaCatalog/classTableInheritance.html

http://martinfowler.com/eaaCatalog/concreteTableInheritance.html

, Если количество дополнительных полей/столбцы является небольшим для подклассов, то единственное наследование таблицы является обычно самым простым иметь дело с.

при использовании PostgreSQL для базы данных и Вы готовы связать себя с определенной для базы данных функцией, это поддерживает наследование таблицы непосредственно:

http://www.postgresql.org/docs/8.3/static/ddl-inherit.html

14
ответ дан hallidave 19 June 2014 в 01:46
поделиться
  • 1
    Я люблю этого разработчика способ сделать вещи, не имея необходимость полагаться на некоторые внешние инструменты)), – haynar 31 October 2018 в 18:36

Сделайте Google ищет на "спецификации генерала реляционное моделирование". Вы найдете статьи о том, как настроить таблицы, которые хранят атрибуты обобщенного объекта (что программисты OO могли бы назвать суперклассом), отдельные таблицы для каждого из специализированных объектов (подклассы), и как использовать внешние ключи для соединения всего этого.

лучшие статьи, IMO, обсуждают спецификацию генерала с точки зрения моделирования ER. Если Вы будете знать, как перевести модель ER в реляционную модель, и отсюда к таблицам SQL, Вы будете знать, что сделать, после того как они показывают Вам, как смоделировать спецификацию генерала в ER.

, Если Вы просто Google на "спецификации генерала", большей части того, что Вы будете видеть, объектно-ориентированы, не реляционный ориентированный. Тот материал может быть полезным также, пока Вы знаете, как преодолеть объектное реляционное несоответствие импеданса.

-1
ответ дан Walter Mitty 19 June 2014 в 01:46
поделиться
  • 1
    Однако макросы могут быть более легко настроены за пределами самого исходного кода (например, из команды сборки) – Lightness Races in Orbit 1 February 2016 в 03:32

Ваш дизайн разумен и следует за корректными правилами нормализации. Вы могли бы пропускать таблицу Vehicle с идентификатором Механизма и Типом (т.е. "родитель" для Быстроходных катеров, Автомобилей и Gokarts..., где Вы сохраните материал как "DesignedByUserId"). Между таблицей Vehicle и Speedboats таблица - одна - к - отношения, и между Механизмом и Speedboat/Cars/GoKarts, там 1-and-only-1 отношения (т.е. механизм может только иметь 1 запись для быстроходного катера, автомобилей или пойти карты)..., хотя большая часть дб не предлагает легкий механизм осуществления для этого.

Одно правило нормализации, которое помогает определить эти виды вещей, - то, что поле должно зависеть только от первичного ключа таблицы. В объединенной таблице, где быстроходный катер, автомобили и gokart результаты испытаний хранятся вместе затем, автомобильные смежные области зависят не только от тестовой даты, но также и от vechicle идентификатора и типа механизма. Первичный ключ для таблицы результатов испытаний является тестовой датой + идентификатор механизма, и тип механизма не то, что делает строку данных тестирования уникальной (т.е. должен там так или иначе провести тест на 01/01/200912:30pm на одном определенном механизме, который является и быстроходным катером и автомобилем... нет... не может быть сделан).

я не объясняю, что правило нормализации particularily хорошо..., но 3-и/4-е/5-е правила нормальных форм всегда смущает меня, когда я прочитал формальные описания. Одно из тех (3-х/4-х/5-х) соглашений с полями в зависимости от первичного ключа и только первичного ключа. Правило делает предположение, что первичный ключ был правильно определен (неправильно defininh, первичный ключ слишком легко сделать).

-3
ответ дан user53794 19 June 2014 в 01:46
поделиться
  • 1
    " кастинг от этого типа до int" наоборот, я думаю; C++ рассматривает перечисления как специализации интервала. – Simon Buchan 26 September 2008 в 11:09
Другие вопросы по тегам:

Похожие вопросы: