问题
SQL Noob here. I am designing a GPS-tracker application and have two tables; a track descriptor table and a track data table. The track descriptor table has the primary key (autoincrement) and the track data table has the foreign key. I would like that after I delete a row from descriptor table, all keys greater than that key are decremented by 1 (does autoincrement do this?). I would also like the same thing to happen in the data table, where all keys greater than deleted are decremented. I am developing for Android and have know how to do it by this method: How do I add and subtract numbers in SQLite for android? . But this seems very resource intensive, is there any way to do the same thing at Table creation (triggers)? Here is the declaration of the two tables (sorry for the Java!!!):
// TRACK_DESCRIPTION table create statement
String createTableTrackDescription =
"CREATE TABLE " + Constants.TABLE_TRACK_DESCRIPTION + "("
+ Constants.COL_TRACK_DESC_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ Constants.COL_TRACK_NAME + " TEXT,"
+ Constants.COL_LOCATION + " TEXT)";
// TRACK_DATA table create statement
String createTableTrackData =
"CREATE TABLE " + Constants.TABLE_TRACK_DATA + "("
+ Constants.COL_TRACK_DATA_ID + " INTEGER,"
+ Constants.COL_LATITUDE + " REAL,"
+ Constants.COL_LONGITUDE + " REAL,"
+ Constants.COL_SPEED + " REAL,"
+ Constants.COL_ALTITUDE + " INTEGER,"
+ Constants.COL_TIMESTAMP + " INTEGER,"
+ "FOREIGN KEY(" + Constants.COL_TRACK_DATA_ID + ") REFERENCES "
+ Constants.TABLE_TRACK_DESCRIPTION + "(" + Constants.COL_TRACK_DESC_ID + "))";
回答1:
does autoincrement do this?
No, in fact coding AUTOINCREMENT
, restricts the re-use of unused rowids.
SQLite creates a unqiue identifier, the rowid, for every row unless you specify WITHOUT ROWID
. This identifier is known as the rowid.
If you code column_name INTEGER PRIMARY KEY
then column_name is an alias for the rowid (e.g. CREATE TABLE x (_id INTEGER PRIMARY KEY, another_column TEXT)
creates table x with 2 columns, column _id is an alias of the rowid)
The rowid will be a higher value (first it is 1) generally the next so normally 1,2 etc, unless the highest number has been used 9223372036854775807
in which case AUTOINCREMENT
if coded or not is considered as follows :-
If AUTOINCREMENT
has been coded (i.e column_name INTEGER PRIMARY KEY AUTOINCREMENT
). AUTOINCREMENT
guarantees a higher rowid, so once 9223372036854775807
has been reached an SQLITE_FULL exception is raised; and
- if you force an insertion using the value
9223372036854775807
for an alias of rowid where AUTOINCREMENT has been coded, then the SQLITE_FULL exception will occur if another insert is attempted.
Without AUTOINCREMENT
SQLITE randomly selects an unused rowid (e.g. your deleted row).
The AUTOINCREMENT
keyword thus ensures that rowid's will be larger.
- It is when
WITHOUT ROWID
is not coded that causes a unique generally incrementing column as the rowid. - It is the use of
column_name INTEGER PRIMARY KEY
that creates an alias for the rowid. - The rowid is not normally visible i.e.
SELECT *
, will not include the rowid column. However; it would include an alias of the rowid. - You can include the rowid by specifying it as a column e.g.
SELECT rowid, *
(the rowid and all other columns). - Coding the
AUTOINCREMENT
keyword imposes extra CPU, memory, disk space, and disk I/O overhead and should be avoided if not strictly needed. It is usually not needed.
You may wish to look at:-
SQLite Autoincrement
Rowid Tables
来源:https://stackoverflow.com/questions/47838907/decrementing-foreign-key-after-primary-key-deletion-sqlite