My understanding is that the only difference between
CREATE TABLE T(ID IDENTITY PRIMARY KEY);
and
CREATE TABLE T(ID BIGINT IDENTITY);
is that the latter is more efficient since the ID column is the row id and as such corresponds the _ROWID_ pseudo-column.
Also, if I do
CREATE TABLE T(ID IDENTITY);
then ID doesn't correspond to _ROWID_ and it isn't even a primary key at all.
Are these assumptions correct?
As suggested I did some tests.
It turns out that all the three statements appear to be equivalent.
ID is always the primary key and corresponds to the _ROWID_ column.
After all, I went with a fourth variant:
CREATE TABLE T(ID BIGINT AUTO_INCREMENT, CONSTRAINT KEY_NAME PRIMARY KEY (ID));
This has the advantage that the primary key's name can be specified.
In the other cases the name was automatically generated, something along the lines of CONSTRAINT_0.
All of this with H2 1.4.190.
Related
I am trying to create Postgres table with Bigserial data type as a promary key. Once I am creating the table the table definition is getting changed to bigint NOT NULL DEFAULT nextval('transactions.transaction_id_seq'::regclass), to this. Please let me know why this happenning?
Thanks In Advance,
Somnath
As noted in the documentation, serials are not "real" data types, but rather convenience wrappers. If you create a serial column, you automatically get
a new sequence ('tablename_columnname_seq`)
an integer column of the appropriate type that takes its default value from the sequence.
the setup for the column to use the sequence.
To quote:
The data types smallserial, serial and bigserial are not true types, but merely a notational convenience for creating unique identifier columns (similar to the AUTO_INCREMENT property supported by some other databases).
CREATE TABLE table (BIGSERIAL id PRIMARY KEY);
is the same as
CREATE SEQUENCE table_id_seq;
CREATE TABLE table (
id bigint NOT NULL DEFAULT nextval('table_id_seq')
);
ALTER SEQUENCE table_id_seq OWNED BY table.id;
Which matches what you are getting.
I've read the rather cool styled BNF grammar for the SQLite create table statement
found here: http://www.sqlite.org/lang_createtable.html
I was wondering how I'd go about creating a link table between these
I have one table, lets say, houses, and another electrical_items.
I want to create a link table to have the house_id and the item_id as a composite key, but I'm not sure how I'd go about doing it, it doesn't appear to allow a primary key to be a foreign key ?
N.B I want a third field pap_tested which stores the date the electrical item in the house was pap_tested so this linking table via composite primary key seems the best approach.
Either of these should work for your association table:
create table house_items (
house_id integer not null,
item_id integer not null,
foreign key (house_id) references houses(id),
foreign key (item_id) references electrical_items(id),
primary key (house_id, item_id)
)
create table house_items (
house_id integer not null references houses(id),
item_id integer not null references electrical_items(id),
primary key (house_id, item_id)
)
You'll probably want separate (single column) indexes on house_items.house_id and house_items.item_id as well.
Just to complement the first answer, it's a good practice to add a name to constraints, like the code below:
create table house_items (
house_id integer not null,
item_id integer not null,
constraint house_items_pk primary key (house_id, item_id),
constraint house_items_house_fk foreign key (house_id) references houses(id),
constraint house_items_items_fk foreign key (item_id) references electrical_items(id));
There is no prohibition about a PRIMARY KEY not also being a FOREIGN KEY for those designs that require this kind of relation. Your problem isn't one of those, however, since the natural PRIMARY KEY in the linking table is a composite of the two columns, each a FOREIGN KEY back to one of the other tables.
I create a table with two foreign keys and options of on update cascade and on delete cascade.
CREATE TABLE category_subcategory
(
category_subcategory_id INTEGER PRIMARY KEY,
category_id INTEGER NOT NULL,
subcategory_id INTEGER NOT NULL,
FOREIGN KEY(category_id) REFERENCES categories(id) ON DELETE CASCADE ON
UPDATE CASCADE,
FOREIGN KEY(subcategory_id) REFERENCES subcategories(subcategory_id) ON
DELETE CASCADE ON UPDATE CASCADE
);
I've developed a software that is in production now & used by 5 clients.
I am using Derby database.
But, Now, I realized that I should've designed one table Primary Key Column with BigInt Datatype instead of Integer type.
So how can I alter the table safely, in the case when this table has relationship with other tables also through this Primary Key Column?
And, If I would like to change type of all table Primary Key Columns from Integer to BigInt, will there be any effect on performance?
Try this:
ALTER TABLE MY_TABLE ADD COLUMN NEW_COLUMN BIGINT;
UPDATE MY_TABLE SET NEW_COLUMN=MY_COLUMN;
ALTER TABLE MY_TABLE DROP COLUMN MY_COLUMN;
RENAME COLUMN MY_TABLE.NEW_COLUMN TO MY_COLUMN;
Discussed here
I have a sqlite table and I need to keep the ids from changing when I VACUUM the database. The documentation says that VACUUM will not change the rowids of a table that has an explicit INTEGER PRIMARY KEY.
So, I created a table with
CREATE TABLE tableName (
"rowid" INTEGER PRIMARY KEY,
"updated" DATETIME DEFAULT (CURRENT_TIMESTAMP),
"description" TEXT
)
But that makes a table with two rowid columns. In SQLite Manager add-on for Firefox I see both, and when I try to access the result set in Java it says "ambiguous column: 'rowid'". Is there a way to explicitly create rowid or do I have to use a different name?
rowid is a column of every SQLite table by default
If a table has a primary key that consists of a single column, and the declared type of that column is INTEGER in any mixture of upper and lower case, then the column becomes an alias for the rowid.
Thus, your rowid column doesn't replace the default rowid. Your key is an alias for the default rowid.
Because of this, you really shouldn't name your column rowid, as it is already used, and will result in "ambiguous column" errors, as you have experienced already.
The documentation is saying that the rowid that SQLite is generating will not be changed if your table contains some INTEGER PRIMARY KEY. The PK does not need to be the rowid.
I'm kinda stuck in a tricky situation with the mySQL DB design for my webservice.The DB had initially this Structure:
CREATE TABLE IF NOT EXISTS `Disease` (
`Name` varchar(20) NOT NULL,
`Age` int(10) unsigned NOT NULL,
`Descriptin` text NOT NULL,
`Sex` varchar(10) NOT NULL,
`Ethnicity` varchar(20) NOT NULL,
PRIMARY KEY (`Name`,`Sex`,`Ethnicity`),
KEY `Sex` (`Sex`),
KEY `Ethnicity` (`Ethnicity`)
)
ALTER TABLE `Disease`
ADD CONSTRAINT `Disease_ibfk_1` FOREIGN KEY (`Sex`) REFERENCES `Sex` (`Sex`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `Disease_ibfk_2` FOREIGN KEY (`Ethnicity`) REFERENCES `Ethnicity` (`Ethnicity`) ON DELETE CASCADE ON UPDATE CASCADE;
So basically Disease(Name,Age,Description,Sex, Ethnicity ) Where Sex and Ethnicity are foreign keys to two tables named Sex and Ethnicity because they can have more than one value.
Now to the question I need to add another Column called Symptoms which will be multivalued but I cant declare it as a foreign key, what i need is this:
example of a row
Disease(Name="DiseaseName",Age="40",Description="is caused by...",Sex="male",Ethnicity="Caucasian",Symptoms"Headache,sorethroat,fever")
So basically i need Symptoms to contain a String of Array but apparently I cant do it since its an RDBMS
Thanks all for you time and efforts!
Don't do that. Instead, normalize your data model: Make a new table "Symptoms", constrained with foreign key "Disease", and make one record for each symptom.
Whenever you start thinking about putting collections of data into a single field, you're effectively trying to build your own mini database inside the database. Thinking that you can outperform and outwit your RDBMS is optimistic at best and most likely leads to unmaintainable code later on.
By the way, does Sex really have to be looked up in a separate table? For micro-categories like that you might like to consider some sort of enum type.
You can accomplish the "array of strings" you're looking for by normalizing your data. Add a new key column to your 'Disease' table. Then create a child table called 'Symptom'. Insert a record for each string with a foreign key back to the 'Disease' table parent record.
In case you didn't notice you misspelled Description in your table creation query.
You need a m:n relation:
Table: Disease
Name
Sex
Ethnicity
Table: Symptoms
ID
Name
Table: Disease_has_Symptoms
Name (FK to Disease)
Sex (FK to Disease)
Ethnicity (FK to Disease)
ID (FK to Symptoms)
(Maybe it's easier to add an ID-column to Disease and reference that inside Disease_has_Symptoms)