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
);
Related
I have two tables - SALES and ITEMS with no primary keys defined. I need to create the entities for the two tables and their composite keys since these tables doesn't have a primary key. Two properties both the table contains are:
Store number
OrderNumber
Can multiple tables have the same composite keys? If not how can I have a composite key in this case?
Yes, no problem. The only restriction is that those primary key constraints can't have the same name.
SQL> create table a (store number, corder number);
Table created.
SQL> create table b (store number, corder number);
Table created.
SQL> alter table a add constraint pka primary key (store, corder);
Table altered.
SQL> alter table b add constraint pka primary key (store, corder);
alter table b add constraint pka primary key (store, corder)
*
ERROR at line 1:
ORA-02264: name already used by an existing constraint
SQL> alter table b add constraint pkb primary key (store, corder);
Table altered.
SQL>
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.
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 am not asking about the differences b/w these 2. After reading the hibernate documentation, i decided to implement them so as to clarify my concepts.
One to Many
1 person linked to Many Addresses
a Set holding the objects of class Address is declared in Person.
CREATE TABLE person_address
(
person_id integer NOT NULL,
address_id integer NOT NULL,
CONSTRAINT person_address_pkey PRIMARY KEY (person_id, address_id),
CONSTRAINT fk9e2338ea36645cd5 FOREIGN KEY (person_id)
REFERENCES person (person_id) ,
CONSTRAINT fk9e2338eaa1a53d5f FOREIGN KEY (address_id)
REFERENCES address (address_id) ,
CONSTRAINT person_address_address_id_key UNIQUE (address_id)
)
In the above case, 4 constraints gets created by Hibernate.
Now have a look at the other mapping.
Many to One
Many Persons linked to a Single Address
a reference of Address class in Person class.
CREATE TABLE person_address
(
person_id integer NOT NULL,
address_id integer NOT NULL,
CONSTRAINT person_address_pkey PRIMARY KEY (person_id),
CONSTRAINT fk9e2338ea246188ab FOREIGN KEY (address_id)
REFERENCES address (address_id) ,
CONSTRAINT fk9e2338eaf88b7809 FOREIGN KEY (person_id)
REFERENCES person (person_id)
)
As you can see there are 3 constraints which Hibernate creates.
It makes complete sense that PRIMARY KEY is (person_id), since different persons are linked to 1 address.
I know the clear-cut differences b/w Primary key and unique keyword.
My question is why Hibernate created the Primary key in the first case to be combination of (person_id, address_id), even knowing that the address_id is unique and could be used as a Primary Key just as in the Second case(Many to One).
Edited :
<key column="PERSON_ID" />
<many-to-many column="ADDRESS_ID" unique="true"
class="org.academy.ansar.UnidirectionalOneToManyMappingWithJoinTable.Address" />
Specifying unique = "true" changes it from many-to-many TO one-to-many
... My question is why Hibernate created the Primary key in the first case to be combination of (person_id, address_id), even knowing that the address_id is unique and could be used as a Primary Key just as in the Second case (Many to One).
In the first case, table person_address is a pairing table between to tables, person and address. And to make the answer really obvious, let's have these records:
Person table
1 - PersonA
2 - PersonB
Address table
1 - AddressX
2 - AddressY
And now, we can have these combinations in the pairing table person_address:
personId, addressId
1 , 1
1 , 2
2 , 1
2 , 2
// 2 , 2 - impossible due to primary key
And that is the answer:
addressId is not unique
personId is not uniq
combination of them is unique
That's how many-to-many does work...
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)