如何在SQLite中向表添加外键?

时间:2019-05-02 21:08:11

标签: java android sql sqlite android-sqlite

我创建了两个表,分别称为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 +

                ")"
        );
}

这是代码Schema代码:

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 个答案:

答案 0 :(得分:2)

将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);
}
  • 默认情况下,外键支持处于关闭状态,除非打开外键支持,否则进行上述编码更改将毫无用处。

然后您需要执行以下一项操作:-

  • 删除应用程序的数据
  • 卸载应用

,然后重新运行该应用程序。

  • 注意,所有现有数据都将丢失。如果您需要保留数据,那可能会相对复杂。

外键

请注意,定义外键仅是定义一个约束(规则),该约束要求将值放入具有该约束的列中,该列是所引用的父表/列中的某一行中的值。 / p>

定义外键约束不会自动使关系发生。也就是说,添加课程时,您仍然必须确定相关术语(常见的误解是这样做)。

您可能希望考虑将定义扩展为包括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 Foreign Key Support

答案 1 :(得分:0)

在类Cols的类CourseTable内定义一个字符串,该字符串将保留此新列的名称,例如:

public static final String TERM_ID = "term_id";

更改表CREATE的{​​{1}}语句:

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的主键。
您需要从设备上卸载应用程序,以便删除数据库,然后重新运行以重新创建数据库。