CREATE TABLE "DEPARTMENT"
( "DEP_NO" NUMBER(*,0) NOT NULL ENABLE,
"SSN" NUMBER(*,0),
"STREET" CHAR(40) NOT NULL ENABLE,
"CITY" CHAR(25) NOT NULL ENABLE,
"NAME" CHAR(50) NOT NULL ENABLE,
"BUDGET" NUMBER(8,2),
CONSTRAINT "PK_DEPARTMENT" PRIMARY KEY ("DEP_NO") ENABLE
) ;
ALTER TABLE "DEPARTMENT" ADD CONSTRAINT "FK_DEPARTMENT_EMPLOYEE" FOREIGN KEY ("SSN")
REFERENCES "EMPLOYEE" ("SSN") ENABLE;
ALTER TABLE "DEPARTMENT" ADD CONSTRAINT "FK_DEPARTMENT_LOCATION" FOREIGN KEY ("STREET", "CITY")
REFERENCES "LOCATION" ("STREET", "CITY") ENABLE;
what is the correct way in building a data base , is it better to create the tables with their primary keys , insert the data and then link these tables to another tables with the foreign key or it is better to create all the tables , link them together and then insert the required data ???
There is no correct way. Both approaches can be used.
The simpler approach is to first create all the tables, indexes and constraints and then to insert the data.
For maximum performance, first create just the tables and the primary key indexes, then insert the data and finally create the additional indexes and the constraints.
Related
Can we have sth like this in MariaDB?
ALTER TABLE `files` ADD
CONSTRAINT `fk_persons_cover`
FOREIGN KEY (`foreign_key`, `model`)
REFERENCES `persons` (`uuid`, "persons_cover")
ON DELETE NO ACTION
ON UPDATE NO ACTION;
I want refrence from files to persons table when files.uuid=persons.uuid and files.model="persons_cover"
Now with this code MariaDB said:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"persons_cover")
ON DELETE NO ACTION
ON UPDATE NO ACTION' at line 4
Is there a solution?
Edit:
I know can use filelable super/interface table like this solution
Or use some auto generated fields in files table like this solution
but they ar not good solution I think.
At first solution we can't find file 1 (row 1) is associated to what? or can't find list of persons 1 (person row with pk = 1) files
At second solution we should add nullable foreign key field per new association!
It should work, if the PERSONS table has a composite primary key (or unique key), encompassing uuid and persons_cover eg
create table persons(
uuid varchar( 100 )
, persons_cover varchar( 100 )
, constraint persons_pkey primary key ( uuid, persons_cover )
) ;
create table files (
uuid varchar( 100 )
, model varchar( 100 )
) ;
alter table files
add constraint fk_persons_cover
foreign key( uuid, model ) references persons( uuid, persons_cover ) ;
If, in your PERSONS table, (only) the UUID column is the primary key column, the composite foreign key may not work. However, in this case, you could add a composite UNIQUE key to the PERSONS table (uuid and person_cover). Should the values stored in the table allow this, then you can add the composite foreign key to FILES.
create table persons2(
uuid varchar( 100 )
, persons_cover varchar( 100 )
, constraint persons_pkey primary key ( uuid ) -- PK: only one column
) ;
-- does not work
alter table files
add constraint fk_persons_cover2
foreign key( uuid, model ) references persons2( uuid, persons_cover ) ;
-- error
-- Failed to add the foreign key constraint. Missing index for constraint 'fk_persons_cover2' in the referenced table 'persons2'
-- add a composite unique key
alter table persons2
add constraint upc_unique unique( uuid, persons_cover ) ;
-- no problem
alter table files
add constraint fk_persons_cover2
foreign key( uuid, model ) references persons2( uuid, persons_cover )
on delete no action
on update no action
;
DBfiddle here.
REFERENCES `persons` (`uuid`, "persons_cover")
No, you can't put a string literal in this line. You must name only column names that exist in the persons table. Typically these are the columns of the primary key of that table.
The foreign key constraint applies to all rows of your table. There's no such thing as a conditional foreign key that only applies on some rows.
I understand you think the workarounds you linked to are not good solutions, but that should be a clue that polymorphic associations are not a good design.
I wrote more about the disadvantages of polymorphic associations in numerous of my answers on Stack Overflow, and in a chapter of my book SQL Antipatterns, Volume 1:
Avoiding the Pitfalls of Database Programming.
I'm trying to set up a 1:1 relationship between two tables Places and People. A person has a home, and when that person is deleted the home should also be deleted. Other tables also use the Places table, so there is no column in the Places table that refers to the People table.
To try and achieve this, I've set the People table up so that when a row is deleted, there is a cascade delete on the foreign key pointing at the Places table row is also deleted.
CREATE TABLE IF NOT EXISTS "People" (
"Id" TEXT NOT NULL CONSTRAINT "PK_People" PRIMARY KEY,
"Name" TEXT NOT NULL,
"HomeId" TEXT NOT NULL,
CONSTRAINT "FK_People_Places_HomeId" FOREIGN KEY ("HomeId") REFERENCES "Places" ("Id") ON DELETE CASCADE
);
However, when I actually tried this, the row in the Places table still existed. Is there any way to fix this?
Fully runnable example
PRAGMA foreign_keys = ON;
CREATE TABLE IF NOT EXISTS "Places" (
"Id" TEXT NOT NULL CONSTRAINT "PK_Places" PRIMARY KEY,
"Name" TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS "People" (
"Id" TEXT NOT NULL CONSTRAINT "PK_People" PRIMARY KEY,
"Name" TEXT NOT NULL,
"HomeId" TEXT NOT NULL,
CONSTRAINT "FK_People_Places_HomeId" FOREIGN KEY ("HomeId") REFERENCES "Places" ("Id") ON DELETE CASCADE
);
DELETE FROM Places;
DELETE FROM People;
INSERT INTO "Places" ("Id", "Name") VALUES ("6f81fa78-2820-48e1-a0a7-b0b71aa38262", "Castle");
INSERT INTO "People" ("Id", "HomeId", "Name") VALUES ("ccb079ce-b477-47cf-adba-9fdac6a41718", "6f81fa78-2820-48e1-a0a7-b0b71aa38262", "Fiona");
-- Should delete both the person and the place, but does not
DELETE FROM "People" WHERE "Id" = "ccb079ce-b477-47cf-adba-9fdac6a41718";
SELECT pl.Name "Place Name",
po.Name "Person Name"
FROM Places pl
LEFT JOIN People po USING(Name)
UNION ALL
SELECT pl.Name,
po.Name
FROM People po
LEFT JOIN Places pl USING(Name)
WHERE pl.Name IS NULL;
The "ON DELETE CASCADE" action for the foreign key that you defined in the table People for the column HomeId which references the column Id of the table Places means that:
whenever you delete a row in the table Places (which is the parent
table in this relationship) all rows in the table People that hold a
reference to the deleted row will also be deleted.
See the demo.
In your case you are deleting a row in the table People and this does not affect at all the table Places.
I'm trying to create 2 (multiple) vertex in SAP HANA like -
Create two table for vertex ITEM and DATASET
CREATE COLUMN TABLE "GREEK_MYTHOLOGY"."ITEM" (
"ITEM_ID" VARCHAR(100) PRIMARY KEY,
"ITEM_NAME" VARCHAR(100)
);
CREATE COLUMN TABLE "GREEK_MYTHOLOGY"."DATASET" (
"DATASET_ID" VARCHAR(100) PRIMARY KEY,
"DATASET_NAME" VARCHAR(100)
);
And creating edge as REFERENCES
CREATE COLUMN TABLE "GREEK_MYTHOLOGY"."REFERENCES" (
"REF_ID" INT UNIQUE NOT NULL,
"SOURCE" VARCHAR(100) NOT NULL
REFERENCES "GREEK_MYTHOLOGY"."ITEM" ("ITEM_ID")
ON UPDATE CASCADE ON DELETE CASCADE,
"TARGET" VARCHAR(100) NOT NULL
REFERENCES "GREEK_MYTHOLOGY"."DATASET" ("DATASET_ID")
ON UPDATE CASCADE ON DELETE CASCADE,
"TYPE" VARCHAR(100)
);
Now I would like to connect both vertex (ITEM and DATASET) with edge REFERENCES like below
CREATE GRAPH WORKSPACE "GREEK_MYTHOLOGY"."GRAPH"
EDGE TABLE "GREEK_MYTHOLOGY"."DATASET"
SOURCE COLUMN "SOURCE"
TARGET COLUMN "TARGET"
VERTEX TABLE "GREEK_MYTHOLOGY"."ITEM" KEY COLUMN "ITEM_ID"
VERTEX TABLE "GREEK_MYTHOLOGY"."DATASET"KEY COLUMN "DATASET_ID"
KEY COLUMN "REF_ID";
But it throws this exception at line VERTEX TABLE "GREEK_MYTHOLOGY"."DATASET"KEY COLUMN "DATASET_ID":
sql syntax error: incorrect syntax near "VERTEX": line 6 col 1 (at pos 200)
Is it possible to create multiple vertex in SAP HANA graph ? If yes then what is the right way to do this.
There's a misunderstanding here. The REFERENCES clause in the CREATE TABLE statement has nothing to do with the graph structure you want to represent.
Instead, it defines a foreign key constraint between the two tables.
The CREATE GRAPH WORKSPACE command only accepts one EDGE TABLE and one VERTEX TABLE as parameters.
However, you can also pass in synonyms or views here.
That way, you could create a view "ALL_ITEMS" like this:
CREATE VIEW "GREEK_MYTHOLOGY"."ALL_ITEMS" as
SELECT "ITEM_ID" as "ID", "ITEM_NAME" as "NAME" FROM "GREEK_MYTHOLOGY"."ITEM"
UNION
SELECT "DATASET_ID" as "ID", "DATASET_NAME" as "NAME" FROM "GREEK_MYTHOLOGY"."DATASET";
and then reference this view:
CREATE GRAPH WORKSPACE "GREEK_MYTHOLOGY"."GRAPH"
EDGE TABLE "GREEK_MYTHOLOGY"."DATASET"
SOURCE COLUMN "SOURCE"
TARGET COLUMN "TARGET"
VERTEX TABLE "GREEK_MYTHOLOGY"."ALL_ITEMS"
KEY COLUMN "NAME";
Using this approach is possible, but you now have to make sure that the "NAME" values are unique and not NULL across both tables.
I have a table created as:
create table association (_id integer unique primary key autoincrement , id_rules integer, id_places integer)";
To avoid replication of entry, I use the statement INSERT OR IGNOR, but it doesn't work. For example,
value (id_rules , id_places) = ("11","1") alredy in table, but using:
INSERT OR IGNORE INTO association (id_rules , id_places) VALUES ("11","1")
a new row is created.
Please, do anyone Know hwere is my mistake?
INSERT OR IGNORE will ignore any rows that would violate a UNIQUE constraint.
The only such constraint is on the _id column, which you did not specify.
If you want to prevent duplicates in those two columns, you have to add a constraint for them to the table definition:
CREATE TABLE association (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
id_rules INTEGER,
id_places INTEGER,
UNIQUE (id_rules, id_places)
);
I am having two tables tbluserlogindetail and tblRoles.
tbluserlogindetail is as follows
CREATE TABLE `tbluserlogindetail` (
`LoginID` varchar(45) NOT NULL,
`Name` varchar(45) DEFAULT NULL,
`Password` varchar(45) DEFAULT NULL,
PRIMARY KEY (`LoginID`),
UNIQUE KEY `LoginID_UNIQUE` (`LoginID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$
EDIT doratesting.tbluserlogindetail;
and my second table tblRoles is as follows
CREATE TABLE `tblroles` (
`RoleID` int(11) NOT NULL,
`LoginID` varchar(45) NOT NULL,
PRIMARY KEY (`RoleID`,`LoginID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$
I tried the the following to assign a primary key for the column LoginID in tblroles table but i don't know where i went wrong can any one help me.
I have gone through the documentation but unable to rectify the error so please help me
ALTER TABLE tblroles
ADD FOREIGN KEY (loginid)
REFERENCES tbluserlogindetail(loginid)
The referenced columns must be unique in the referenced table. Try one of these options:
The primary key on tbluserlogindetail is (ID, loginid) so you could use that as your foreign key instead of (loginid). This will require you to add a column tbluserlogindetail_ID to tblroles.
Try adding a unique index to the LoginID column of the tbluserlogindetail table. This is only possible if it is actually unique.
Also, why is your primary key on tbluserlogindetail defined as PRIMARY KEY (ID, LoginID)? The ID field is an auto-increment field and is already unique. So why do you also include the LoginID as part of the primary key? I think you need to go back to your table design and rethink which columns to choose as your primary keys.
this is just guess/ assumption ,i like to share here,
PRIMARY KEY (ID,LoginID)
in tbluserlogindetail are considered as surrogate key,
when we execute the child table,That is tblroles,
child table expected primary key in parent table,
but actually we created the surrogate key, due to this reason, i alter query failed,
ALTER TABLE tblroles ADD FOREIGN KEY (LoginID) REFERENCES tbluserlogindetail(LoginID)
This is my assumption, give feedback for my answer,
I did following changes to execute the Alter table command:
1.tblroles create with given Create query command, after created i manually deleted the
LoginID primary key in tblroles table,
Changed varchar to int in LoginID,
in tbluserlogindetail, deleted the ID AUTO_INCREMENT,Pk.
Check i updated ALTER query