Для сопоставления иерархий классов с таблицами реляционной базы данных мне известны три шаблона:
- Одна таблица для всей иерархии. Каждая строка будет содержать объединение всех атрибутов классов иерархии. Это, на мой взгляд, трудно поддерживать, если есть изменения в классах. Конечно, каждой строке нужен идентификатор типа.
- Одна таблица для каждого конкретного класса иерархии. В этом случае таблица, представляющая конкретный класс, содержит атрибуты этого класса плюс атрибуты всех абстрактных базовых классов. Абстрактные классы не отображаются напрямую.
- Одна таблица для каждого абстрактного и конкретного класса. В этом случае каждый отдельный класс напрямую отображается в одну таблицу.
Преимущество 1. состоит в том, что довольно легко достичь того, что вы хотите сделать, то есть прочитать все объекты, которые являются частью вашей иерархии классов. Ты тратишь немного места, хотя. В 2. вы могли читать каждую таблицу в подвыборе одного оператора select с постоянными фиктивными значениями для атрибутов других классов, а затем объединять их вместе в одном операторе SQL. В 3. запрос становится немного более сложным: вам нужно ВНУТРИ СОЕДИНИТЬ таблицы конкретных классов с таблицами базовых классов в подвыборах. В любом случае вам не понадобится ПОЛНОЕ НАРУЖНОЕ СОЕДИНЕНИЕ.
Добавление:
Предположим, у вас есть иерархия объектов с классом Person
и двумя подклассами, Student
и Teacher
. В 2. вы бы создали две таблицы, STUDENT и TEACHER, в каждой из которых есть столбец NAME. В таблице STUDENT есть дополнительный столбец YEAR, а в таблице TEACHER - столбец SALARY. Ваш запрос может выглядеть так:
SELECT 'STUDENT' AS TYPE, NAME, YEAR, NULL AS SALARY FROM STUDENT
UNION SELECT 'TEACHER' AS TYPE, NAME, NULL AS YEAR, SALARY FROM TEACHER
, который вы можете затем извлечь и использовать для заполнения ваших объектов данными или отображения, используя SimpleCursorAdapter
или что угодно.