我创建了两个表,分别称为 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?
最佳答案
更改 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
}
- 列名当然可以是您想要的
更改为类(class)表创建 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(列的类型亲和性),这不是问题。之所以将其包含在内,是因为大多数人会指定列类型而不是应用默认值(数字)。
重要
然后重写onConfigure来调用setForeignKeyConstraintsEnabled 传递真实。
例如:-
@Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}
- 默认情况下,外键支持处于关闭状态,除非打开外键支持,否则上述编码更改将毫无用处。
然后您需要执行以下操作之一:-
- 删除应用数据
- 卸载应用
然后重新运行应用程序。
- 注意任何现有数据都将丢失。如果您需要保留数据,那么这可能相对复杂。
外键
请注意,定义外键只是定义一个约束(规则),该约束要求将值放入具有约束的列中,该列必须是引用的父表/列的某一行中的值。
定义外键约束不会自动使关系发生。也就是说,在添加类(class)时您仍然必须确定相关术语(一个常见的误解是它会这样做)。
您可能希望考虑扩展定义以包括 ON DELETE 和 ON UPDATE 操作,例如 CASCADE。例如ON DELETE CASCADE 会在删除学期行时删除类(class)表中的子行。同样,如果术语表中的值发生更改,ON UPDATE CASCADE 将更新类(class)表中子级的引用值(这些可以使生活更简单)。
例如你可以使用:-
TermDbSchema.CourseTable.Cols.TERM_LINK + " INTEGER REFERENCES " + TermDbSchema.TermTable.NAME + "(_id) ON DELETE CASCADE ON UPDATE CASCADE" + //<<<<<<<<<< ADDED
关于java - 如何在 SQLite 中向表添加外键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55960261/