In Redshift, how do you add multiple constraints to a table after creating the table? - foreign-keys

In Redshift, is there a way to add multiple constraint to an already created table?
Step ONE, created the table (say month ago)
CREATE TABLE test_user
(
account_id BIGINT DEFAULT NULL encode mostly32,
ingest_timestamp BIGINT DEFAULT NULL ENCODE mostly32,
ingest_date TIMESTAMP DEFAULT NULL ENCODE delta32k,
user_id BIGINT NOT NULL encode mostly32,
group_id BIGINT NOT NULL encode mostly32,
department_id BIGINT NOT NULL encode mostly32,
name VARCHAR(255) DEFAULT NULL ENCODE LZO,
mobile VARCHAR(15) DEFAULT NULL ENCODE LZO,
phone VARCHAR(15) DEFAULT NULL ENCODE LZO,
user_language VARCHAR(15) DEFAULT NULL ENCODE runlength,
deleted INT DEFAULT NULL ENCODE mostly8,
created_at TIMESTAMP DEFAULT NULL ENCODE delta32k,
updated_at TIMESTAMP DEFAULT NULL ENCODE delta32k,
PRIMARY KEY (user_id)
)
sortkey (account_id)
Step TWO, created more tables like 'test_group','test_department'
Step THREE, after a month, I am planning to add multiple constraints to 'test_user' table like this(but in separate query)
ALTER TABLE test_user ADD CONSTRAINT FK_1 FOREIGN KEY (group_id) REFERENCES test_group (group_id);
ALTER TABLE test_user ADD CONSTRAINT FK_1 FOREIGN KEY (department_id) REFERENCES test_department (department_id);
The above succeeds.
However, Is there a way to add multiple constraints in single query?
Tried like this,
option 1 -> ALTER TABLE test_user ADD CONSTRAINT FK_1 FOREIGN KEY (group_id) REFERENCES test_group (group_id),ADD CONSTRAINT FK_1 FOREIGN KEY (department_id) REFERENCES test_department (department_id);
option 2 -> ALTER TABLE test_user ADD CONSTRAINT FK_1 FOREIGN KEY (group_id) REFERENCES test_group (group_id), FK_1 FOREIGN KEY (department_id) REFERENCES test_department (department_id);
But got this error for both case,
An error occurred when executing the SQL command:
ALTER TABLE test_user ADD CONSTRAINT FK_1 FOREIGN KEY (group_id) REFERENCES test_group (group_id), FK_2 FOREIGN KEY (department_id) REFERENCES test_department (department_id); REFERENCES helpdesk_user (user_id)
ERROR: syntax error at or near "FK_2"
Is there a way to add multiple constraint to an already created table?
Please help

It doesn't matter when you define them, or even if you define them at all.
Redshift ignores constraints. Defining them has no effect, except that the optimizer may use them as additional information when creating the access plan.
However, I have created and used massive (billions of rows) databases in redshift, and I didn't define a single constraint of any kind and it all ran amazingly fast.
Answer: Don't bother.

The ALTER TABLE documentation does not indicate that it is possible to specify multiple constraints in one statement:
ALTER TABLE table_name
{
ADD table_constraint |
DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ] |
OWNER TO new_owner |
RENAME TO new_name |
RENAME COLUMN column_name TO new_name |
ADD [ COLUMN ] column_name column_type
[ DEFAULT default_expr ]
[ ENCODE encoding ]
[ NOT NULL | NULL ] |
DROP [ COLUMN ] column_name [ RESTRICT | CASCADE ] }
where table_constraint is:
[ CONSTRAINT constraint_name ]
{ UNIQUE ( column_name [, ... ] ) |
PRIMARY KEY ( column_name [, ... ] ) |
FOREIGN KEY (column_name [, ... ] )
REFERENCES reftable [ ( refcolumn ) ]}
On a side note, Redshift Pitfalls And How To Avoid Them has an interesting examination of the impact of constraints on Redshift queries (see "Beware of Constraints" section).

Related

Why MySQL workbench is making all my foreign keys unique?

I've created a MySQL Model with a few tables, some of them with fk's to another table. I usually export the SQL from MySQL Model to my database using the "Forward Engineer SQL CREATE Script" inside File -> Export -> Forward Engineer SQL CREATE Script. The problem here is that when I generate the creation script, all my fk's become unique. I didn't check UQ option in MySQL Model but it creates a script with unique fk's anyway, so, I need to change the SQL file generated and remove all the unwanted uniques. Anyone has a clue why this is happening?
Generated script:
CREATE TABLE IF NOT EXISTS `u514786799_detranleiloes`.`Lotes` (
`createdAt` DATE NOT NULL,
`updatedAt` DATE NOT NULL,
`id` INT UNIQUE NOT NULL AUTO_INCREMENT,
`LeiloesId` INT UNIQUE NOT NULL,
`conservado` TINYINT NULL,
`numero` INT NOT NULL,
`CRDsId` INT UNIQUE NULL,
PRIMARY KEY (`id`),
INDEX `fk_Lotes_Leiloes_idx` (`LeiloesId` ASC),
INDEX `fk_Lotes_CRDs1_idx` (`CRDsId` ASC),
CONSTRAINT `fk_Lotes_Leiloes`
FOREIGN KEY (`LeiloesId`)
REFERENCES `u514786799_detranleiloes`.`Leiloes` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Lotes_CRDs1`
FOREIGN KEY (`CRDsId`)
REFERENCES `u514786799_detranleiloes`.`CRDs` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 1;

Having trouble summing columns in SQL Server joined view

Moi guys, Matt here. I'm having trouble with a relatively complicated view. I have a parts and service table that each have unique identifiers for a given part/service. I'm trying to link these to a service invoice table and subsequent view as a M:N relationship, so I've set up intermediary relational tables, with both the invoice number (invoice primary key) and part/service number (part/service primary key) as the combined primary key. Here's my code for the whole relationship and view:
CREATE TABLE service_invoice
( servinv_Num VARCHAR2(10) CONSTRAINT serv_snum_PK PRIMARY KEY,
servinv_EmpID NUMBER(6) CONSTRAINT serv_empnum_FK REFERENCES employee(empID),
servinv_CustID NUMBER(6) CONSTRAINT serv_custid_FK REFERENCES customer(custID),
servinv_VIN VARCHAR2(25) CONSTRAINT serv_VIN_FK REFERENCES vehicle(vehicle_vin),
servinv_Terms VARCHAR2(6) CONSTRAINT serv_trms_NN NOT NULL,
servinv_Date DATE );
CREATE TABLE Parts
( PartID VARCHAR2(10) CONSTRAINT Part_PartID_PK PRIMARY KEY,
PartDesc VARCHAR2(50) CONSTRAINT Part_PartDesc_NN NOT NULL,
PartCharge NUMBER(4,2) CONSTRAINT Part_PartCharge_NN NOT NULL );
CREATE TABLE Service
( ServiceID VARCHAR2(10) CONSTRAINT Serv_ServID_PK PRIMARY KEY,
ServDesc VARCHAR2(50) CONSTRAINT Serv_ServName_NN NOT NULL,
ServCharge NUMBER(4,2) CONSTRAINT Serv_ServCharge_NN NOT NULL );
CREATE TABLE Serv_SI_Rel
( SI_num VARCHAR2(10) CONSTRAINT ServSI_SInum_FK REFERENCES service_invoice(servinv_Num),
ServiceID VARCHAR2(10) CONSTRAINT ServSI_ServID_FK REFERENCES Service(ServiceID),
CONSTRAINT ServSI_SInum_ServID_PK PRIMARY KEY(SI_num, ServiceID) );
CREATE TABLE Parts_SI_Rel
( SI_num VARCHAR2(10) CONSTRAINT PartSI_SInum_FK REFERENCES service_invoice(servinv_Num),
PartID VARCHAR2(10) CONSTRAINT PartSI_PartID_FK REFERENCES Parts(PartID),
CONSTRAINT PartSI_SInum_PartID_PK PRIMARY KEY(SI_num, PartID) );
CREATE OR REPLACE VIEW ServiceInvoiceDoc
AS
(
SELECT si.servinv_Num, si.servinv_Date, si.servinv_Terms,
es.empName,
sc.custName, sc.custHouse, sc.custCity,
sc.custState, sc.custZIP, sc.custPhone, sc.custEmail,
sv.vehicle_VIN, sv.vehicle_mileage,
srel.ServiceID,
prel.PartID,
s.ServDesc, s.ServCharge,
p.PartDesc, p.PartCharge,
SUM(s.ServCharge) TotalServCharges,
SUM(p.PartCharge) TotalPartsCharges,
( SUM(s.ServCharge)+SUM(p.PartCharge) ) SubTotalCharges,
( SUM(s.ServCharge)+SUM(p.PartCharge) )*0.0825 Taxes,
( SUM(s.ServCharge)+SUM(p.PartCharge) )*1.0825 TotalCharges
FROM service_invoice si
JOIN employee es
ON (es.empID = si.servinv_EmpID)
JOIN customer sc
ON (sc.custID = si.servinv_CustID)
JOIN vehicle sv
ON (sv.vehicle_VIN = si.servinv_VIN)
LEFT OUTER JOIN Serv_SI_Rel srel
ON (srel.SI_Num = si.servinv_Num)
LEFT OUTER JOIN Parts_SI_Rel prel
ON (prel.SI_num = si.servinv_Num)
JOIN Parts p
ON (prel.PartID = p.PartID)
JOIN Service s
ON (srel.ServiceID = s.ServiceID) );
The error I get has to do with summing the individual parts and service charges in the M:N relationship. Here's the error code from the run:
ORA-00937: not a single-group group function
I've tried fixing with a group by command, but the grouping identifier (service invoice) isn't included on the part or service tables, and the joins don't seem to link these up for a group. e.g. I tried calling GROUP BY si.servinv_Num
Can this be resolved at all or is it completely wrong? I have the option of dropping the M:N relationship as a 1:M and simply making a separate invoice for each part/service charge, but I would prefer to keep it compact and professional.
Any help would be greatly appreciated. Thank you so much for your time!
a) wrong tag
b) I'd imagine you would need to list all columns in group by clause that aren't aggregated, as per Oracle
...
group by si.servinv_Num, si.servinv_Date, si.servinv_Terms,
es.empName,
sc.custName, sc.custHouse, sc.custCity,
sc.custState, sc.custZIP, sc.custPhone, sc.custEmail,
sv.vehicle_VIN, sv.vehicle_mileage,
srel.ServiceID,
prel.PartID,
s.ServDesc, s.ServCharge,
p.PartDesc, p.PartCharge

coding many to many relationship in c++ sqlite3

I trying to code a many to many relationship in c++ sqlite3.
in the diagram below,
managers can add many job opportunities.
jobs opportunities is being add by many managers
my create table statements
"CREATE TABLE Manager(" \
"manager_id INTEGER PRIMARY KEY NOT NULL,"\
"name varchar(45) NOT NULL);"
"CREATE TABLE jobs ("
"jobId INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"\
"jobTitle varchar(45) NOT NULL);"
"CREATE TABLE Add ("
"manager_id,jobId INTEGER PRIMARY KEY NOT NULL,"\
"date varchar(45) NOT NULL,"\
"FOREIGN KEY(manager_id) REFERENCES Manager(manager_id),"\
"FOREIGN KEY(job_id) REFERENCES jobs(job_id));";
my manager table is populated with the following information
1|john
2|bob
let's say manager john has added two jobs,jobTitle jobA and jobB
then my insert statement code will look like this.http://pastebin.com/0E8CzPgX
then my jobs tables is populated with the following information
1|jobA
2|jobB
the final step is to take the id of john(manager id = 1) and the two jobsId(1,2) and add it inside
the add table. I don't have an idea of how should I code
so that the add table will become like this.
add table
manager_id|job_id|date
1 | 1 |30-01-2014
1 | 2 |30-01-2014
please advise.thanks
Do you mean something like
sql = "INSERT INTO Add(manager_id,jobId,date) VALUES (?,?,?);";
?
Your problem seems to be that you defined jobID to be the primary key of the table Add, which you don't need.
jobId INTEGER PRIMARY KEY NOT NUL
A common approach to many-to-many relations in a database is to include an intermediate table.
This intermediate table (let's call it Manager_jobs) would have at least 2 columns, both referring to other tables via foreign key. The first attribute would be the primary key of Manager, the second one the primary key of jobs.
Each time you add a job, you just add an entry to Manager_jobs with the foreign keys respectively.
So, Manager_jobs would look like this:
ManagerID | JobID
==========|======
4 | 2
3 | 2
4 | 1
As you can see, Manager_jobs can encode that a Manager has multiple jobs assigned and vice versa.
This approach, of course, requires you to have some form of primary key for both data tables.

Trying to add foreign key in mysql with heidisql

I've been trying to add a foreign key to my table using heidisql and I keep getting the error 1452.
After reading around I made sure all my tables were running on InnoDB as well as checking that they had the same datatype and the only way I can add my key is if I drop all my data which I don't intend to do since I have spent quite a few hours on this.
here is my table create code:
CREATE TABLE `data` (
`ID` INT(10) NOT NULL AUTO_INCREMENT,
#bunch of random other columns stripped out
`Ability_1` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
#more stripped tables
`Extra_Info` SET('1','2','3','Final','Legendary') NOT NULL DEFAULT '1' COLLATE 'utf8_unicode_ci',
PRIMARY KEY (`ID`),
UNIQUE INDEX `ID` (`ID`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=650;
here is table 2
CREATE TABLE `ability` (
`ability_ID` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
#stripped columns
`Name_English` VARCHAR(12) NOT NULL COLLATE 'utf8_unicode_ci',
PRIMARY KEY (`ability_ID`),
UNIQUE INDEX `ability_ID` (`ability_ID`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=165;
Finally here is the create code along with the error.
ALTER TABLE `data`
ADD CONSTRAINT `Ability_1` FOREIGN KEY (`Ability_1`) REFERENCES `ability` (`ability_ID`) ON UPDATE CASCADE ON DELETE CASCADE;
/* SQL Error (1452): Cannot add or update a child row: a foreign key constraint fails (`check`.`#sql-ec0_2`, CONSTRAINT `Ability_1` FOREIGN KEY (`Ability_1`) REFERENCES `ability` (`ability_ID`) ON DELETE CASCADE ON UPDATE CASCADE) */
If there is anything else I can provide please let me know this is really bothering me. I'm also using 5.5.27 - MySQL Community Server (GPL) that came with xampp installer.
If you are using HeidiSQL it is pretty easy.
Just see the image, click on the +Add to add foreign keys.
I prefer GUI way of creating tables and its attribute because it saves time and reduces errors.
I found it. Sorry everyone. The problem was that I had 0 as a default value for my fields while my original table had no value for 0.
Here is how you can do it ;
Create your Primary keys. For me this was straight forward so I won't post how to do that here
To create your FOREIGN KEYS you need to change the table / engine type for each table from MyIASM to InnoDb. To do this Select the table on the right hand side then select the OPTIONS tab on the right hand side and change the engine from MyIASM to InnoDb for every table.

Can't create table (errno: 150) InnoDB adding foreign key constraints

Really hate to use other people's time, but it seems the problem is just not going away.
I considered all recommendations at http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/ and at http://forums.mysql.com/read.php?22,19755,19755#msg-19755 but nothing.
hope that someone points to a stupid mistake.
here are the tables:
CREATE TABLE IF NOT EXISTS `shop`.`category` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`category_id` INT(11) NOT NULL ,
`parent_id` INT(11) NULL DEFAULT '0' ,
`lang_id` INT(11) NOT NULL ,
...other columns...
PRIMARY KEY (`id`, `category_id`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `shop`.`product_category` (
`category_id` INT(11) NOT NULL ,
`product_id` INT(11) NOT NULL ,
INDEX `fk_product_category_category1_zxc` (`category_id` ASC) ,
CONSTRAINT `fk_product_category_category1_zxc`
FOREIGN KEY (`category_id` )
REFERENCES `shop`.`category` (`category_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
Error Code: 1005. Can't create table 'shop.product_category' (errno: 150)
You need an index on category_id in the category table (I see it's part of the primary key, but since it's the second column in the index, it can not be used). The field you are referencing in a foreign key always should be indexed.
In my case the issue was more like what was described in the first article you've linked to.
So I just had to make sure that:
Referenced Column is an index,
both Referencing Column and Referenced Column share the same type and length, i.e. e.g. both are INT(10),
both share the same not null, unsigned, zerofill etc. configuration.
both tables are InnoDB!
Here's the query template where Referencing Column is referencing_id and Referenced Column is referenced_id:
ALTER TABLE `db`.`referencing`
ADD CONSTRAINT `my_fk_idx`
FOREIGN KEY (`referencing_id`)
REFERENCES `db`.`referenced`(`referenced_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
Update 2016-03-13: Ran into this problem again, ended up finding my own answer. This time it didn't help though. Turns out the other table was still set to MyISAM, as soon as I changed it to InnoDB everything worked.