Как добавить внешний ключ в таблицу в SQLite? - PullRequest
2 голосов
/ 03 мая 2019

Я создал две таблицы с именами TermTable и CourseTable. Я хочу, чтобы у CourseTable был внешний ключ для ссылки на TermTable.

Это код, в котором я создаю таблицы:


public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table " + TermDbSchema.TermTable.NAME + "(" +
                "_id integer primary key autoincrement, " +
                TermDbSchema.TermTable.Cols.UUID + ", " +
                TermDbSchema.TermTable.Cols.TITLE + ", " +
                TermDbSchema.TermTable.Cols.START_DATE + ", " +
                TermDbSchema.TermTable.Cols.END_DATE +
                ")"
        );
//I want to give CourseTable a foreign key to reference TermTable^^
        db.execSQL("create table " + TermDbSchema.CourseTable.NAME + "(" +
                "_id integer primary key autoincrement, " +
                TermDbSchema.CourseTable.Cols.UUID + ", " +
                TermDbSchema.CourseTable.Cols.TITLE + ", " +
                TermDbSchema.CourseTable.Cols.START_DATE + ", " +
                TermDbSchema.CourseTable.Cols.END_DATE + ", " +
                TermDbSchema.CourseTable.Cols.COURSE_STATUS + ", " +
                TermDbSchema.CourseTable.Cols.OPTIONAL_NOTE + ", " +
                TermDbSchema.CourseTable.Cols.MENTOR_NAME + ", " +
                TermDbSchema.CourseTable.Cols.MENTOR_PHONE + ", " +
                TermDbSchema.CourseTable.Cols.MENTOR_EMAIL +

                ")"
        );
}

Это код кода схемы:

public class TermDbSchema {

public static final class TermTable {
        public static final String NAME = "terms";
        public static final class Cols {
            public static final String UUID = "uuid";
            public static final String TITLE = "title";
            public static final String START_DATE = "startdate";
            public static final String END_DATE = "enddate";
        }
    }
    public static final class CourseTable {
        public static final String NAME = "courses";
        public static final class Cols {
            public static final String UUID = "uuid";
            public static final String TITLE = "title";
            public static final String START_DATE = "startdate";
            public static final String END_DATE = "enddate";
            public static final String COURSE_STATUS = "coursestatus";
            public static final String OPTIONAL_NOTE = "optionalnote";
            public static final String MENTOR_NAME = "mentorname";
            public static final String MENTOR_PHONE = "mentorphone";
            public static final String MENTOR_EMAIL = "mentoremail";        
        }
}

Как добавить внешний ключ к CourseTable, чтобы он мог ссылаться на TermTable?

Ответы [ 2 ]

2 голосов
/ 03 мая 2019

Измените CourseTable, чтобы иметь другой столбец для ссылки (ссылка, отношение, ассоциация, сопоставление - все остальные термины) : -

public static final class CourseTable {
    public static final String NAME = "courses";
    public static final class Cols {
        public static final String UUID = "uuid";
        public static final String TITLE = "title";
        public static final String START_DATE = "startdate";
        public static final String END_DATE = "enddate";
        public static final String COURSE_STATUS = "coursestatus";
        public static final String OPTIONAL_NOTE = "optionalnote";
        public static final String MENTOR_NAME = "mentorname";
        public static final String MENTOR_PHONE = "mentorphone";
        public static final String MENTOR_EMAIL = "mentoremail"; 
        public static final String TERM_LINK = "termlink"    //<<<<<<<<<< ADDED   
    }
  • имя столбца, конечно, может быть таким, как вы хотите

Измените создание SQL для таблицы курсов, чтобы добавить ограничение внешнего ключа.

         db.execSQL("create table " + TermDbSchema.CourseTable.NAME + "(" +
            "_id integer primary key autoincrement, " +
            TermDbSchema.CourseTable.Cols.UUID + ", " +
            TermDbSchema.CourseTable.Cols.TITLE + ", " +
            TermDbSchema.CourseTable.Cols.START_DATE + ", " +
            TermDbSchema.CourseTable.Cols.END_DATE + ", " +
            TermDbSchema.CourseTable.Cols.COURSE_STATUS + ", " +
            TermDbSchema.CourseTable.Cols.OPTIONAL_NOTE + ", " +
            TermDbSchema.CourseTable.Cols.MENTOR_NAME + ", " +
            TermDbSchema.CourseTable.Cols.MENTOR_PHONE + ", " +
            TermDbSchema.CourseTable.Cols.MENTOR_EMAIL + ", " + //<<<<<<<<<< CHANGED
            TermDbSchema.CourseTable.Cols.TERM_LINK + " INTEGER REFERENCES " + TermDbSchema.TermTable.NAME + "(_id)" + //<<<<<<<<<< ADDED

            ")"
    );
  • вы можете захотеть придерживаться ваших конвенций без INTEGER (сходство типов столбца), это не будет проблемой. Он был включен, потому что большинство из них будет указывать типы столбцов, а не применять по умолчанию (NUMERIC).

Важно

Затем переопределите onConfigure , чтобы вызвать setForeignKeyConstraintsEnabled , передавая true.

например. : -

@Override
public void onConfigure(SQLiteDatabase db) {
    super.onConfigure(db);
    db.setForeignKeyConstraintsEnabled(true);
}
  • По умолчанию поддержка внешнего ключа отключена, поэтому внесенные выше изменения кодирования будут бесполезны, если не включена поддержка внешнего ключа.

Затем вам нужно будет выполнить 1 из следующих действий: -

  • Удалить данные приложения
  • Удалить приложение

, а затем снова запустите приложение.

  • Примечание любые существующие данные будут потеряны. Если вам нужно сохранить данные, это может быть относительно сложно.

Иностранные ключи

Обратите внимание, что определение внешнего ключа - это ТОЛЬКО определение ограничения (правила), которое требует, чтобы значение было помещено в столбец, для которого установлено ограничение, в качестве значения в одной из строк родительской таблицы / столбца, на которую есть ссылка.

Определение ограничения по внешнему ключу НЕ создает автоматически отношения. То есть вам все равно придется определять связанный термин при добавлении курса (распространенное заблуждение состоит в том, что он делает это).

Возможно, вы захотите расширить определение, включив в него действия ON DELETE и ON UPDATE, такие как CASCADE. например ON DELETE CASCADE при удалении строки термина (если) удалял дочерние строки в таблице курса. Аналогичным образом, ON UPDATE CASCADE обновит ссылочное значение дочерних элементов в таблице курса, если это значение будет изменено в таблице терминов (это может упростить жизнь).

например. Вы можете использовать: -

    TermDbSchema.CourseTable.Cols.TERM_LINK + " INTEGER REFERENCES " + TermDbSchema.TermTable.NAME + "(_id) ON DELETE CASCADE ON UPDATE CASCADE" + //<<<<<<<<<< ADDED

Вы можете обратиться к Поддержка внешнего ключа SQLite

0 голосов
/ 03 мая 2019

Определите строку внутри класса Cols класса CourseTable, которая будет содержать имя этого нового столбца, например:

public static final String TERM_ID = "term_id";

Измените оператор CREATE таблицы CourseTable:

db.execSQL("create table " + TermDbSchema.CourseTable.NAME + "(" +
        "_id integer primary key autoincrement, " +
        TermDbSchema.CourseTable.Cols.UUID + ", " +
        TermDbSchema.CourseTable.Cols.TITLE + ", " +
        TermDbSchema.CourseTable.Cols.START_DATE + ", " +
        TermDbSchema.CourseTable.Cols.END_DATE + ", " +
        TermDbSchema.CourseTable.Cols.COURSE_STATUS + ", " +
        TermDbSchema.CourseTable.Cols.OPTIONAL_NOTE + ", " +
        TermDbSchema.CourseTable.Cols.MENTOR_NAME + ", " +
        TermDbSchema.CourseTable.Cols.MENTOR_PHONE + ", " +
        TermDbSchema.CourseTable.Cols.MENTOR_EMAIL + ", " +
        TermDbSchema.CourseTable.Cols.TERM_ID + " INTEGER, " +
        "FOREIGN KEY (" + TermDbSchema.CourseTable.Cols.TERM_ID +
        ") REFERENCES " + TermDbSchema.TermTable.NAME + "(_id)" + 
        ")"
);

Этот новый столбец будет ссылаться на столбец _id, который является ПЕРВИЧНЫМ КЛЮЧОМ TermTable.Вам необходимо удалить приложение с устройства, чтобы база данных была удалена, а затем повторно запустить ее, чтобы воссоздать базу данных.

...