I am developing a MySQL database using Workbench. I want two send two fields from a newly created record to another table. I would then like to update the original table with newly created data from the second table. I was looking to implement this with triggers, unless there is a better way of course :) My attempt was a fail when I went to upload it(see below)
Specifically, I would like tc_Event to send the ID & tc_EventTags_ID to tc_EventTags to fill in tc_Tag_ID & tc_Event_ID. Afterwards I want the ID of tc_EventTags sent back to tc_Event to the tc_EventTags_ID field.
Thanks for any help.
-- -----------------------------------------------------
-- Table `mcontest`.`tc_EventTags`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mcontest`.`tc_EventTags` (
`ID` INT NOT NULL AUTO_INCREMENT ,
`tc_Tag_ID` INT NOT NULL ,
`tc_Event_ID` INT NOT NULL ,
PRIMARY KEY (`ID`) ,
INDEX `fk_tc_EventTags_tc_Tag1` (`tc_Tag_ID` ASC) ,
INDEX `fk_tc_EventTags_tc_Event1` (`tc_Event_ID` ASC) ,
CONSTRAINT `fk_tc_EventTags_tc_Tag1`
FOREIGN KEY (`tc_Tag_ID` )
REFERENCES `mcontest`.`tc_Tag` (`ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_tc_EventTags_tc_Event1`
FOREIGN KEY (`tc_Event_ID` )
REFERENCES `mcontest`.`tc_Event` (`ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = MyISAM;
-- -----------------------------------------------------
-- Table `mcontest`.`tc_Event`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mcontest`.`tc_Event` (
`ID` INT NOT NULL AUTO_INCREMENT ,
`date` DATE NOT NULL ,
`time` TIME NOT NULL ,
`location` VARCHAR(45) NOT NULL ,
`description` VARCHAR(45) NOT NULL ,
`tc_EventTags_ID` INT NULL ,
`tc_Orgs_ID` INT NOT NULL ,
`tc_PersonEvent_ID` INT NOT NULL ,
PRIMARY KEY (`ID`) ,
INDEX `fk_tc_Event_tc_EventTags1` (`tc_EventTags_ID` ASC) ,
INDEX `fk_tc_Event_tc_Orgs1` (`tc_Orgs_ID` ASC) ,
INDEX `fk_tc_Event_tc_PersonEvent1` (`tc_PersonEvent_ID` ASC) ,
CONSTRAINT `fk_tc_Event_tc_EventTags1`
FOREIGN KEY (`tc_EventTags_ID` )
REFERENCES `mcontest`.`tc_EventTags` (`ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_tc_Event_tc_Orgs1`
FOREIGN KEY (`tc_Orgs_ID` )
REFERENCES `mcontest`.`tc_Orgs` (`ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_tc_Event_tc_PersonEvent1`
FOREIGN KEY (`tc_PersonEvent_ID` )
REFERENCES `mcontest`.`tc_PersonEvent` (`ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = MyISAM;
USE `mcontest`;
DELIMITER $$
USE `mcontest`$$
CREATE TRIGGER eventTag_Trigger
AFTER insert ON tc_Event
FOR EACH ROW BEGIN
INSERT INTO tc_EventTags values('',NEW.tc_Event_ID);
END;
END$$
DELIMITER ;
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
Why have put a tc_EventTags_ID in table tc_Event? What is the logic behind that?
I mean that the relationship between the 2 tables would be (I guess): 1 Event - many EventTags. This is already achieved by the tc_EventTags.tc_Event_ID which is a Foreign Key to tc_Event.
To answer your question:
As it is now, the Trigger tries for every row inserted in table Event, to add a row in table EventTag. But it will fail for 2 reasons:
EventTag has 2 Constraints (Foreign keys) which have to be fulfilled for the triggered insert to succeed. So, tc_Event_ID is ok but tc_Tag_ID has to be NOT NULL and reference the Tag table but the value you supply, '', probably is not in table Tag.
EDIT: the value you supply, '', is also a CHAR while it should be INT.
But trigger will probably not be started at all, since every time you insert a row in table Event, those constraints have to be fulfilled and one of them is the tc_EventTags_ID which references EventTag table. But EventTag table is empty. Do you see the circular logic here?
Related
thanks for taking time to look at my thread.
I'm 'trying to' create a MySQL table for item categories with a column for the parent category in the table. I linked it back to the table as a fk and intend to insert (0) into the column value for items that have no parents.
Here is the table definition:
-- -----------------------------------------------------
-- Table `mydb`.`itemCategories`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`itemCategories` (
`itecat_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`category` VARCHAR(60) NOT NULL ,
`parentCat` INT UNSIGNED NOT NULL ,
PRIMARY KEY (`itecat_id`) ,
UNIQUE INDEX `uniqueCat` (`category` ASC) ,
INDEX `fk_itemCategories_itemCategories1` (`parentCat` ASC) ,
CONSTRAINT `fk_itemCategories_itemCategories1`
FOREIGN KEY (`parentCat` )
REFERENCES `mydb`.`itemCategories` (`itecat_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
When I try to insert a new row, it gives the following error:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`mydb`.`itemCategories`, CONSTRAINT `fk_itemCategories_itemCategories1` FOREIGN KEY (`parentCat`) REFERENCES `itemCategories` (`itecat_id`) ON DELETE NO ACTION)
Any help on how to fix this, or a better way to do it, would be very much appreciated.
Thanks!
0 is a value! You should use NULL as the "empty field".
Good day
I'm trying to solve an issue with foreign key relationship between three tables. Basically I have two secondary tables, each one has two foreign keys and each foreign key is referenced to a single primary key in the third table.
This same issue happens in a much larger database, however due to its complexity, size and possible copyright issues. I had no choice but to isolate the problem and create a replica that would result in the same issue. However if you must know, the same two tables that reference the main table People are just two in a universe of dozens of the same kind in the database in question.
My hope is that someone can point the problem and maybe provide a solution that wouldn't effect much of the current structure, so that I can apply it myself, probably to all other tables because from what I see of the database diagram, its likely they will all suffer from the same problem. Database authorship is not mine, which only adds to one's confusion when looking at the diagram.
The SQL create script:
CREATE SCHEMA IF NOT EXISTS `sampleBD` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
USE `sampleBD` ;
-- -----------------------------------------------------
-- Table `sampleBD`.`People`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `sampleBD`.`People` (
`PeopleID` INT NOT NULL AUTO_INCREMENT ,
`Name` VARCHAR(200) NOT NULL ,
`EntryDate` DATETIME NULL ,
`EntryBy` INT NULL ,
PRIMARY KEY (`PeopleID`) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `sampleBD`.`PeopleNumberId`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `sampleBD`.`PeopleNumberId` (
`PeopleNumberIdID` INT NOT NULL AUTO_INCREMENT ,
`PeopleID` INT NOT NULL ,
`NumberId` INT(11) NOT NULL ,
`EntryDate` DATETIME NULL ,
`EntryBy` INT NULL ,
PRIMARY KEY (`PeopleNumberIdID`) ,
INDEX `PeopleID` (`PeopleID` ASC) ,
INDEX `EntryBy` (`EntryBy` ASC) ,
CONSTRAINT `PeopleID`
FOREIGN KEY (`PeopleID` )
REFERENCES `sampleBD`.`People` (`PeopleID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `EntryBy`
FOREIGN KEY (`EntryBy` )
REFERENCES `sampleBD`.`People` (`PeopleID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `sampleBD`.`PeopleCbi`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `sampleBD`.`PeopleCbi` (
`PeopleCbiID` INT NOT NULL AUTO_INCREMENT ,
`PeopleID` INT NOT NULL ,
`Cbi` INT NOT NULL ,
`EntryDate` DATETIME NULL ,
`EntryBy` INT NULL ,
PRIMARY KEY (`PeopleCbiID`) ,
INDEX `PessoaID` (`PeopleID` ASC) ,
INDEX `EntryBy` (`EntryBy` ASC) ,
CONSTRAINT `PessoaID`
FOREIGN KEY (`PeopleID` )
REFERENCES `sampleBD`.`People` (`PeopleID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `EntryBy`
FOREIGN KEY (`EntryBy` )
REFERENCES `sampleBD`.`People` (`PeopleID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
The script is able to create the first and second tables, however when it reaches the third table it returns an error code.
Error Code: 1005. Can't create table 'samplebd.peoplecbi' (errno: 121)
It's a foreign key problem, but I'm not sure how it could be fixed without altering the current structure of the table or tables involved.
Thanks for the help.
This looks like a name conflict between foreign key constraint names. Constraint names must be unique in a database, like table names are.
So just choose another name for the constraint EntryBy in the 3rd table. It will not affect any of the functionality you have.
This was originally going to be an "update" on the logical schema presented in another question here: Getting ERROR 1701, ERROR 1452 and ERROR 1305 errors in MySQL - Need some expertise...
I think I have successfully verified this schema to 1st and 2nd Normal Form, but am unsure if this meets 3rd Normal Form. Here is the model in question:
And here is the associated code (note: for some reason I cannot recreate 1:1 relationships in the sql code as illustrated in the logical model above):
-- database_schema.sql.
-- This sql script creates the structure.
-- of the rugby club database.
DROP DATABASE IF EXISTS database_rugby;
CREATE DATABASE database_rugby;
USE database_rugby;
-- Create the "person" table.
--
-- This table has one:one relationships
-- with the parent, coach and player
-- tables.
DROP TABLE IF EXISTS `person` ;
CREATE TABLE `person` (
`personID` INT(5) NOT NULL AUTO_INCREMENT ,
`firstName` VARCHAR(50) NOT NULL ,
`lastName` VARCHAR(50) NOT NULL ,
`dateOfBirth` DATE NOT NULL ,
`streetAddress` VARCHAR(150) NOT NULL ,
`suburbAddress` VARCHAR(150) NULL DEFAULT NULL ,
`cityAddress` VARCHAR(150) NOT NULL ,
`photo` BLOB NULL DEFAULT NULL ,
PRIMARY KEY (`personID`))
ENGINE = InnoDB;
-- Create the "parent" table.
DROP TABLE IF EXISTS `parent` ;
CREATE TABLE `parent` (
`parentID` INT(5) NOT NULL ,
`personID` INT(5) NOT NULL ,
PRIMARY KEY (`parentID`, `personID`),
FOREIGN KEY (`personID`) REFERENCES `person` (`personID`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- Create the "school" table.
DROP TABLE IF EXISTS `school` ;
CREATE TABLE `school` (
`schoolID` INT(5) NOT NULL AUTO_INCREMENT ,
`schoolName` VARCHAR(100) NOT NULL ,
PRIMARY KEY (`schoolID`))
ENGINE = InnoDB;
-- Create the "player" table.
--
-- Inherits fields from the "person"
-- and "school" tables.
DROP TABLE IF EXISTS `player` ;
CREATE TABLE `player` (
`playerID` INT(5) NOT NULL ,
`personID` INT(5) NOT NULL ,
`schoolID` INT(5) NOT NULL ,
PRIMARY KEY (`playerID`, `personID`),
FOREIGN KEY (`personID`)
REFERENCES `person` (`personID`)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (`schoolID`)
REFERENCES `school` (`schoolID`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- Create the "coach" table.
DROP TABLE IF EXISTS `coach`;
CREATE TABLE `coach`(
`coachID` INT(5) NOT NULL ,
`dateBeganCoaching` DATE NOT NULL ,
`personID` INT(5) NOT NULL ,
PRIMARY KEY (`coachID`, `personID`),
FOREIGN KEY (`personID`)
REFERENCES `person` (`personID`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- Create the "family" table.
--
-- This is a linking table
-- that describes the many:many
-- relationship between "parent"
-- and "player" tables.
DROP TABLE IF EXISTS `family` ;
CREATE TABLE `family` (
`parentID` INT(5) NOT NULL ,
`playerID` INT(5) NOT NULL ,
FOREIGN KEY (`playerID` )
REFERENCES `player` (`playerID`)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (`parentID`)
REFERENCES `parent` (`parentID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- Create the "grade" table.
DROP TABLE IF EXISTS `grade`;
CREATE TABLE `grade`(
`gradeID` INT(5) NOT NULL AUTO_INCREMENT ,
`gradeName` VARCHAR(50) NOT NULL ,
`minWeight` INT(3) NOT NULL ,
`maxWeight` INT(3) NOT NULL ,
`minAge` INT(3) NOT NULL ,
`maxAge` INT(3) NOT NULL ,
`ballSize` INT(1) NOT NULL ,
PRIMARY KEY (`gradeID`) )
ENGINE = InnoDB;
-- Create the "coachQualification" table.
DROP TABLE IF EXISTS `coachQualification` ;
CREATE TABLE `coachQualification` (
`qualID` INT(5) NOT NULL AUTO_INCREMENT ,
`qualName` CHAR(5) NOT NULL ,
`gradeID` INT(5) NOT NULL ,
PRIMARY KEY (`qualID`) ,
FOREIGN KEY (`gradeID`)
REFERENCES `grade` (`gradeID`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- Create the "homePhone" table.
DROP TABLE IF EXISTS `homePhone` ;
CREATE TABLE `homePhone` (
`homePhoneID` INT(5) NOT NULL AUTO_INCREMENT ,
`homeNumber` CHAR(9) NOT NULL ,
PRIMARY KEY (`homePhoneID`))
ENGINE = InnoDB;
-- Create the "mobilePhone" table.
DROP TABLE IF EXISTS `mobilePhone` ;
CREATE TABLE `mobilePhone` (
`mobilePhoneID` INT(5) NOT NULL AUTO_INCREMENT ,
`mobileNumber` CHAR(10) NULL DEFAULT NULL ,
PRIMARY KEY (`mobilePhoneID`))
ENGINE = InnoDB;
-- Create the "emailAddress" table.
DROP TABLE IF EXISTS `emailAddress` ;
CREATE TABLE `emailAddress` (
`emailAddressID` INT(5) NOT NULL AUTO_INCREMENT ,
`emailAddress` CHAR(10) NULL DEFAULT NULL ,
PRIMARY KEY (`emailAddressID`))
ENGINE = InnoDB;
-- Create the "Contact" table
--
-- This is a linking table
-- that describes the many:many
-- relationships between "person"
-- and the "homePhone", "mobilePhone",
-- and "emailAddress" tables.
DROP TABLE IF EXISTS `contact` ;
CREATE TABLE `contact` (
`personID` INT(5) NOT NULL ,
`homePhoneID` INT(5) NOT NULL ,
`mobilePhoneID` INT(5) NULL DEFAULT NULL ,
`emailAddressID` INT(5) NULL DEFAULT NULL ,
FOREIGN KEY (`personID` )
REFERENCES `person` (`personID`)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (`homePhoneID`)
REFERENCES `homePhone` (`homePhoneID`)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (`mobilePhoneID`)
REFERENCES `mobilePhone` (`mobilePhoneID`)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (`emailAddressID`)
REFERENCES `emailAddress` (`emailAddressID`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- Create the "qualificationSet" table.
--
-- This is a linking table
-- that describes the many:many
-- relationship between "coach"
-- and "coachQualification" tables.
DROP TABLE IF EXISTS `qualificationSet` ;
CREATE TABLE `qualificationSet` (
`coachID` INT(5) NOT NULL ,
`qualID` INT(5) NOT NULL ,
FOREIGN KEY (`coachID`)
REFERENCES `coach` (`coachID`)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (`qualID`)
REFERENCES `coachQualification` (`qualID`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- Create the "team" table.
DROP TABLE IF EXISTS `team` ;
CREATE TABLE `team` (
`teamID` INT(5) NOT NULL AUTO_INCREMENT ,
`teamName` VARCHAR(50) NOT NULL ,
`teamYear` INT(2) NOT NULL ,
`gradeID` INT(5) NOT NULL ,
PRIMARY KEY (`teamID`) ,
FOREIGN KEY (`gradeID`)
REFERENCES `grade` (`gradeID`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- Create the "teamAllocation" table
--
-- this is a linking table for a
-- many:many relationship between
-- team and player tables.
DROP TABLE IF EXISTS `teamAllocation` ;
CREATE TABLE `teamAllocation` (
`teamID` INT(5) NOT NULL ,
`playerID` INT(5) NOT NULL ,
FOREIGN KEY (`teamID` )
REFERENCES `team` (`teamID`)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (`playerID`)
REFERENCES `player` (`playerID`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- Create the "teamCoachAllocation" table.
--
-- This is a linking table
-- that describes the many:many
-- relationship between "coach"
-- and "team" tables.
DROP TABLE IF EXISTS `teamCoachAllocation` ;
CREATE TABLE `teamCoachAllocation` (
`coachID` INT(5) NOT NULL ,
`teamID` INT(5) NOT NULL ,
FOREIGN KEY (`coachID`)
REFERENCES `coach` (`coachID`)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (`teamID`)
REFERENCES `team` (`teamID`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
From these links below:
http://en.wikipedia.org/wiki/First_normal_form
http://en.wikipedia.org/wiki/Second_normal_form
http://en.wikipedia.org/wiki/Third_normal_form
This is my understanding of Normalisation to 3NF:
First normal form means to not allow repeating values
Second normal form means 1NF and attributes are dependant on whole primary key and not part of a primary key (I think of this as partitioning tables if values in that table need to relate to eachother in some way and have comparisons made).
Third normal form means 2NF and no transistive values (e.g if x = y and y = z, x = z)
Putting that knowledge from theory into practice is quite hard for me, especially translating that "practise" into working, normalised MySQL code. If someone is able to help me go through the model and give me some pointers about normalising the model to 3NF, I would appreciate it very much.
Thanks in advance!
I think this isn't in 3NF, around the contact table. If I'm wrong this is still a bad way of storing the data and should probably be changed.
Sorry if this is a little confused...
It is entirely possible to have the following structure in your contact table as the entire table is the primary key:
+----------+-------------+---------------+---------+
| personid | homephoneid | mobilephoneid | emailid |
+----------+-------------+---------------+---------+
| 1 | 1 | 1 | 1 |
| 1 | 1 | 1 | 2 |
| 1 | 1 | 2 | 3 |
+----------+-------------+---------------+---------+
As you can see both homephoneid and mobilephoneid are duplicated so updating the table homephone will result 3 updates to contact.
I disagree with the data-model as you require a person to have a homehone I don't have one, only a mobile. In this situation, when creating a new person you have to also create a new contact and a new homephone.
As contact is just a primary key and a primary key value cannot be null, you also require the creation of a mobilephone and an emailaddress, which means that person is dependent on emailaddress.
As emailaddress is dependent on contact, which in turn is dependent on person you've created a circular dependency, which breaks 3NF.
As I see it you have a two options if you want to ensure that people have to have a home phone number:
If you only want a person to have one homephone then add this
into the person table. It's unique contact level information and
should be stored there.
If you want to enable people to have multiple home phone numbers -
remembering that multiple people can use the same phone number - but
don't care about mobiles then you need to create a table
personhomephones, say, with the primary key personid,
homephoneid and not put homephoneid in the contact table.
Personally I wouldn't do either of these. I wouldn't ensure that someone has to have a home phone number but instead a primary phone number, where you don't care what type it is. I would allow people to add different methods of contact but allow these not to exist
This would require the following structure:
person - add primaryPhoneID
primaryphone ( primaryphoneID, phonenumber) - PK primaryphoneID
Then for the contact methods that are allowed to not exist:
contactType ( contactTypeID, contactType ) - PK contactTypeID
contact ( contactID, contactTypeID, value ) - PK contactID, contactTypeID
personContact ( personID, contactID, contactTypeID ) - PK everything
Whilst this may result in duplication between contact and primaryphone they are distinct bits of data and I think this is fine. If you're insistent on not allowing any duplication at all you'd have to separate out the phones from the other methods of contact, which makes the model more complicated:
phonetype ( phoneTypeId, phoneType )
phone ( phoneID, phoneTypeID, phonenumber) - PK phoneID, phoneTypeID
contactPhone ( personID, phoneTypeID, phoneID ) - PK everything
There is an algorithm to eventually decompose each relation in your schema in order to get an equivalent schema in 3NF. Google is good for that!!
To get tips about your schema design you should at least describe the context and the functional constraints about the entities you need to represent.
I need some help to structure some tables that will help me out having a good personalized way to have different access name per client with personalized allowed commands in each acess level.
So consider client A has create site Y, which he wants to create the follow access groups:
Admin (have all acess),
VIP (can access room 1),
Basic (can access louge),
Banned (cannot enter at all)
The same way client A create his personalized access I want all my other clients to be able to create their own personalized access where they can name it anything they see fit in their own language and later just put in what commands they will have access to by being on that given access level.
I have the follow tables as example (sorry that this isnt a datagram, work bench keep crashing on me when I make example and I am open to suggestion for alternatives to create datagrams as good as or better than workbench):
client TABLE:
id int,
username varchar,
password varchar,
status varchar
site TABLE:
id int,
owner_client_id,
name varchar
access TABLE:
id int,
name varchar,
commands int (bitmask?)
site_access TABLE
id int,
client_id,
site_id,
access_id
commands
id int,
action varchar,
alias varchar,
description varchar
On my application all the commands actions are alredy pre-defined and the user cannot change them in what they do or the default name, but they are allowed to create alias.
So let's say I have the command kick, they could make an alias to name it "k" or "explosion" or they could name the alias anything they want.
Some of my doubts:
Initially I tought of using site_access to link everything together, client that has access to site and what access it has and from their access what commands each have, is that a good way to go with it ?
I have many commands that will be pulled from the database but since some have their own alias I dont thin I could use a bitmask for the acess and still being able to query the alias if not null could I so I would have to use a list of commands or are there good options ?
What engine should I use, InnoDB or MyISAM in my case ?
Is it ok to mix engines or not a good idea at all ?
What should I change on my current table structure and could you provide any samples too (if possible) ?
UPDATE:
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='TRADITIONAL';
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
USE `mydb` ;
-- -----------------------------------------------------
-- Table `mydb`.`clients`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`clients` ;
CREATE TABLE IF NOT EXISTS `mydb`.`clients` (
`id` INT NOT NULL,
`username` VARCHAR(45) NOT NULL ,
`password` VARCHAR(45) NOT NULL ,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `username_UNIQUE` (`username` ASC) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`sites`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`sites` ;
CREATE TABLE IF NOT EXISTS `mydb`.`sites` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(45) NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`groups`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`groups` ;
CREATE TABLE IF NOT EXISTS `mydb`.`groups` (
`id` INT NOT NULL ,
`name` VARCHAR(45) NOT NULL ,
`alias` VARCHAR(45) NOT NULL ,
`commands` VARCHAR(45) NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`membership`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`membership` ;
CREATE TABLE IF NOT EXISTS `mydb`.`membership` (
`client_id` INT NOT NULL ,
`group_id` INT NOT NULL ,
PRIMARY KEY (`client_id`, `group_id`) ,
INDEX `client_id` (`client_id` ASC) ,
INDEX `group_id` (`group_id` ASC) ,
CONSTRAINT `client_id`
FOREIGN KEY (`client_id` )
REFERENCES `mydb`.`clients` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `group_id`
FOREIGN KEY (`group_id` )
REFERENCES `mydb`.`groups` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`access`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`access` ;
CREATE TABLE IF NOT EXISTS `mydb`.`access` (
`site_id` INT NOT NULL ,
`group_id` INT NOT NULL ,
PRIMARY KEY (`site_id`, `group_id`) ,
INDEX `site_id` (`site_id` ASC) ,
INDEX `group_id` (`group_id` ASC) ,
CONSTRAINT `site_id`
FOREIGN KEY (`site_id` )
REFERENCES `mydb`.`sites` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `group_id`
FOREIGN KEY (`group_id` )
REFERENCES `mydb`.`groups` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
I would do it a bit differently
Client Table
Group Table
Membership Table (Client - Group)
Site Table
Access Table (Group Site)
Also see pages 12-13 in this link for ideas http://support.sas.com/resources/papers/proceedings09/265-2009.pdf
I'm running the following MySQL query (trimmed down), generated automatically by MySQL Workbench and I get the following error:
Error Code: 1005
Can't create table 'regula.reservation' (errno: 121)
I'm not very proficient with databases and this error is not very informative.
What is the problem here?
-- -----------------------------------------------------
-- Table `regula`.`Users`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `regula`.`Users` ;
CREATE TABLE IF NOT EXISTS `regula`.`Users` (
`idUsers` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`name` TEXT NOT NULL ,
`type` TEXT NOT NULL ,
`pwd` TEXT NOT NULL ,
PRIMARY KEY (`idUsers`) ,
UNIQUE INDEX `idUsers_UNIQUE` (`idUsers` ASC) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `regula`.`Projects`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `regula`.`Projects` ;
CREATE TABLE IF NOT EXISTS `regula`.`Projects` (
`idProjects` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`ownerId` INT UNSIGNED NOT NULL ,
`name` TEXT NOT NULL ,
`date` DATE NOT NULL ,
`time` TIME NOT NULL ,
`place` TEXT NOT NULL ,
`itemType` INT NOT NULL ,
PRIMARY KEY (`idProjects`) ,
UNIQUE INDEX `idProjects_UNIQUE` (`idProjects` ASC) ,
INDEX `ownerId` (`ownerId` ASC) ,
CONSTRAINT `ownerId`
FOREIGN KEY (`ownerId` )
REFERENCES `regula`.`Users` (`idUsers` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `regula`.`ItemTypes`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `regula`.`ItemTypes` ;
CREATE TABLE IF NOT EXISTS `regula`.`ItemTypes` (
`idItemTypes` INT UNSIGNED NOT NULL ,
`prjId` INT UNSIGNED NOT NULL ,
`parentId` INT UNSIGNED NULL DEFAULT NULL ,
`name` TEXT NOT NULL ,
PRIMARY KEY (`idItemTypes`) ,
INDEX `prjId` (`prjId` ASC) ,
INDEX `parentId` (`parentId` ASC) ,
CONSTRAINT `prjId`
FOREIGN KEY (`prjId` )
REFERENCES `regula`.`Projects` (`idProjects` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `parentId`
FOREIGN KEY (`parentId` )
REFERENCES `regula`.`ItemTypes` (`idItemTypes` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `regula`.`Reservation`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `regula`.`Reservation` ;
CREATE TABLE IF NOT EXISTS `regula`.`Reservation` (
`idReservation` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`prjId` INT UNSIGNED NOT NULL ,
`itemTypeId` INT UNSIGNED NOT NULL ,
`userId` INT UNSIGNED NOT NULL ,
PRIMARY KEY (`idReservation`) ,
INDEX `prjId` (`prjId` ASC) ,
INDEX `itemTypeId` (`itemTypeId` ASC) ,
INDEX `userId` (`userId` ASC) ,
CONSTRAINT `prjId`
FOREIGN KEY (`prjId` )
REFERENCES `regula`.`Projects` (`idProjects` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `itemTypeId`
FOREIGN KEY (`itemTypeId` )
REFERENCES `regula`.`ItemTypes` (`idItemTypes` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `userId`
FOREIGN KEY (`userId` )
REFERENCES `regula`.`Users` (`idUsers` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Error 121 means that there is a foreign key constraint error. Since you're using InnoDB, you can use SHOW ENGINE INNODB STATUS after running the failed query to get an explanation in the LATEST FOREIGN KEY ERROR section. Having run your SQL myself, I get this:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
101210 14:55:50 Error in foreign key constraint creation for table `regula`.`Reservation`.
A foreign key constraint of name `regula`.`prjId`
already exists. (Note that internally InnoDB adds 'databasename'
in front of the user-defined constraint name.)
Note that InnoDB's FOREIGN KEY system tables store
constraint names as case-insensitive, with the
MySQL standard latin1_swedish_ci collation. If you
create tables or databases whose names differ only in
the character case, then collisions in constraint
names can occur. Workaround: name your constraints
explicitly with unique names.
Basically, you need to give your prjId constraint name a unique name in the last table. Constraint/foreign key names are global to a database, so they cannot be reused in different tables. Just change the last
CONSTRAINT `prjId`
to
CONSTRAINT `prjId2`
The error code 121 comes when you try to map the foreign key.
Basically it comes when your foreign key name already exists in the database.
For example:
ALTER TABLE `photokiosk`.`kiosk_event`
ADD CONSTRAINT `event_booking_id`
FOREIGN KEY `event_booking_id` (`event_booking_id`)
REFERENCES `event_booking` (`event_booking_id`)
If foreign key with the name event_booking_id is already mapped with the other table.
To get rid of this issue, please change the foreign key name, not the column name.
You will get this error message if you try to use a constraint name which already exists in the table.
Here 'prjId' already exists in table regula.ItemTypes. So, you can't use the same constraint name on table 'regula.reservation' again.