Is this relationship OneToMany or ManyToMany? - mysql

I have two tables ARTICLE and FAQ ( frequently asked questions ). I'm trying to establish a relationship between these two tables but I'm confused!
What I want to achieve is that article can have many FAQ. So for this should I create a pivot table or just reference a FK in FAQ table?
What I tried but I'm not sure that the below flow is right or not?
Article table:
CREATE TABLE IF NOT EXISTS `article` (
`id` int(11) UNSIGNED NOT NULL,
`title` varchar(255) DEFAULT NULL,
`slug` varchar(255) DEFAULT NULL,
`description` longtext NOT NULL,
PRIMARY KEY (`id`)
);
FAQ Table Schema:
CREATE TABLE IF NOT EXISTS `eb_faq` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`faq_category_id` bigint(20) UNSIGNED DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`question` text NOT NULL,
`answer` text NOT NULL,
PRIMARY KEY (`id`)
);
Pivot:
CREATE TABLE IF NOT EXISTS `article_linked_faq` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`article_id` int(11) DEFAULT NULL,
`faq_id` int(11) DEFAULT NULL,
`order_by` int(11) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
);

This schema will indeed allow an article to have multiple FAQs, but also allows one FAQ to be linked to multiple articles. If that's what you want, great! If not then I'd suggest removing the pivot table and adding article_id into eb_faq.

No, you just need to add foreign key in faq table, it will create the relationship between both tables. There is no need to create a third table
CREATE TABLE IF NOT EXISTS `eb_faq` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`articleId` int(11),
`faq_category_id` bigint(20) UNSIGNED DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`question` text NOT NULL,
`answer` text NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (articleId) REFERENCES article(id)
);

Related

There can be only one auto column error when giving AUTO_INCREMENT value

I am using phpMyAdmin while trying to create a table.
The definition is as follows
CREATE TABLE `koment` (
`movieID` int(11) NOT NULL,
`userID` int(11) NOT NULL,
`id` int(11) NOT NULL,
`text` varchar(255) DEFAULT NULL,
PRIMARY KEY (`movieID`,`userID`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
I want to have id as an auto increment variable but it seems that I can't make it thus even though it is a primary key(I needed the id attribute because a user can write many comments on the same movie). So I don't understand why I still get this error. Thanks in advance.
I'd rather advise you to have clear PRIMARY KEY which is AUTO_INCREMENT and UNIQUE KEY like in your example:
CREATE TABLE `koment` (
`movieID` int(11) NOT NULL,
`userID` int(11) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY (`movieID`,`userID`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `koment` (
`movieID` int(11) NOT NULL,
`userID` int(11) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(255) DEFAULT NULL,
PRIMARY KEY (`movieID`,`userID`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Creating a relationship between tables and creating a foreign key

How to make relation between these tables?
CREATE TABLE `categories` (
`id` smallint(6) NOT NULL,
`name` varchar(256) NOT NULL,
`description` text NOT NULL,
`position` smallint(6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB;
CREATE TABLE `pm` (
`id` bigint(20) NOT NULL,
`id2` int(11) NOT NULL,
`title` varchar(256) NOT NULL,
`user1` bigint(20) NOT NULL,
`user2` bigint(20) NOT NULL,
`message` text NOT NULL,
`timestamp` int(10) NOT NULL,
`user1read` varchar(3) NOT NULL,
`user2read` varchar(3) NOT NULL
) ENGINE=INNODB;
CREATE TABLE `topics` (
`parent` smallint(6) NOT NULL,
`id` int(11) NOT NULL,
`id2` int(11) NOT NULL,
`title` varchar(256) NOT NULL,
`message` longtext NOT NULL,
`authorid` int(11) NOT NULL,
`timestamp` int(11) NOT NULL,
`timestamp2` int(11) NOT NULL,
PRIMARY KEY (`id`,`id2`)
) ENGINE=INNODB;
CREATE TABLE `users` (
`id` bigint(20) NOT NULL,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`avatar` text NOT NULL,
`signup_date` int(10) NOT NULL
) ENGINE=INNODB;
If a topics has a users as an author,
if you are storing the id value of the users that is the author of the topics in the authorid column,
The "author" relationship is a one-to-many relationship. A topics is related to one (or zero) users. (And a users can be the "author" of zero, one or more topics.)
Here's an example of a foreign key definition to have the database (InnoDB storage engine) enforce the integrity of that relationship:
ALTER TABLE topics
ADD CONSTRAINT FK_topics_users_author
FOREIGN KEY (authorid) REFERENCES users (id)
ON UPDATE CASCADE ON DELETE RESTRICT

How to add foreign key in table using existing column, without losing data?

I have a table in which I need to add foreign key on an existing column. Following is create table:
CREATE TABLE `itemtx` (
`itemTxid` int(11) NOT NULL AUTO_INCREMENT,
`itemcode` varchar(1) NOT NULL,
`weight` decimal(7,3) DEFAULT NULL,
`txtype` varchar(10) DEFAULT 'Pickup',
`tripstopid` int(11) NOT NULL,
`barcode` varchar(25) DEFAULT NULL,
`bagcount` int(11) DEFAULT '1',
PRIMARY KEY (`itemTxid`)
) ENGINE=InnoDB AUTO_INCREMENT=33524 DEFAULT CHARSET=latin1
I need to add foreign key on tripstopid column. I cannot drop or empty table as it contains data. Following is the referenced table:
CREATE TABLE `tripstop` (
`tripstopid` int(11) NOT NULL AUTO_INCREMENT,
`tripid` int(11) DEFAULT NULL,
`locationName` varchar(100) DEFAULT NULL,
`userName` varchar(100) DEFAULT NULL,
`locationid` int(11) DEFAULT NULL,
`datetime` varchar(20) DEFAULT NULL,
`createts` varchar(20) DEFAULT NULL,
`latitude` double DEFAULT NULL,
`longitude` double DEFAULT NULL,
`userid` int(11) DEFAULT NULL,
`tid` int(11) DEFAULT NULL,
PRIMARY KEY (`tripstopid`)
) ENGINE=InnoDB AUTO_INCREMENT=4691 DEFAULT CHARSET=latin1
How can I do this without losing my data?
You can achieve this by following:
ALTER TABLE itemtx
ADD FOREIGN KEY (tripstopid) REFERENCES tripstop(tripstopid);
Verified by creating tables, inserting data in them and then updating table for foreign key, previously entered data is not lost.

Creating a MySQL Table but get error

I get
errnno 150: InnoDB Documentation
Supports transactions, row-level locking, and foreign keys
Here is the SQL:
-- Table structure for table `Serving_Info`
--
CREATE TABLE IF NOT EXISTS `Serving_Info` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`Food_Value` varchar(40) NOT NULL,
`Food_name` varchar(40) NOT NULL,
`Served_On` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`Oncall` varchar(128) NOT NULL,
Foreign key(`Oncall`) REFERENCES `employees`(`name`),
Foreign key(`Food_name`) REFERENCES `Foods`(`Food_name`),
PRIMARY KEY (`Oncall`,`Food_name`, `Served_On`)
);
Any idea what is causing the error? I have tried making id part of the primary key but that isn't solving the problem either.
Here are the statements for the tables I am referencing:
CREATE TABLE IF NOT EXISTS `employees` (
`id_user` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL,
`email` varchar(64) NOT NULL,
`phone_number` varchar(16) NOT NULL,
`username` varchar(16) NOT NULL,
`password` varchar(32) NOT NULL,
`confirmcode` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id_user`)
);
--
-- Table structure for table `Foods`
--
CREATE TABLE IF NOT EXISTS `Foods` (
`Food_name` varchar(40) NOT NULL,
`CostPerRefill` double NOT NULL,
PRIMARY KEY (`Food_name`)
);
I just tried the below but I get the same error:
--
-- Table structure for table `Serving_Info`
--
CREATE TABLE IF NOT EXISTS `Serving_Info` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`Food_Value` varchar(40) NOT NULL,
`Food_name` varchar(40) NOT NULL,
`Served_On` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`Oncall` varchar(128),
Foreign key(`Oncall`) REFERENCES `employees`(`name`),
Foreign key(`Food_name`) REFERENCES `Foods`(`Food_name`),
PRIMARY KEY (`id`),
UNIQUE (`Oncall`,`Food_name`, `Served_On`)
);
Your problem is that the reference is to employees.name rather than employees.id_user. Try this:
CREATE TABLE IF NOT EXISTS `Serving_Info` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`Food_Value` varchar(40) NOT NULL,
`Food_name` varchar(40) NOT NULL,
`Served_On` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`Oncall` int,
PRIMARY KEY (`id`),
Foreign key(`Oncall`) REFERENCES `employees`(`id_user`),
Foreign key(`Food_name`) REFERENCES `Foods`(`Food_name`),
UNIQUE (`Oncall`,`Food_name`, `Served_On`)
);
Otherwise, change the employees table so name has an index:
CREATE TABLE IF NOT EXISTS `employees` (
`id_user` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL ,
`email` varchar(64) NOT NULL,
`phone_number` varchar(16) NOT NULL,
`username` varchar(16) NOT NULL,
`password` varchar(32) NOT NULL,
`confirmcode` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id_user`),
KEY (name)
);
In practice, if you are going to use name this way, you should probably make that unique rather than just key.

cannot add second FK : got error can't create table'.jobstatus\#sql-32c_12f2f.frm' (errno:150)

CREATE TABLE `job` (
`jobId` int(11) NOT NULL auto_increment,
`jobcode` varchar(25) default NULL,
`jobname` varchar(255) default NULL,
`location` varchar(255) default NULL,
`budget` int(10) unsigned default NULL,
`year_type` varchar(100) default NULL,
`worklineId` int(11) default NULL,
PRIMARY KEY (`jobId`),
KEY `NewIndex` (`worklineId`),
FOREIGN KEY (`worklineId`) REFERENCES `workline` (`worklineId`)
) TYPE=InnoDB;
CREATE TABLE `subjob` (
`subjobId` int(11) NOT NULL auto_increment,
`subjobcode` varchar(25) default NULL,
`subjobname` varchar(255) default NULL,
`subjobbudget` int(11) unsigned default NULL,
`jobgoal_date` date default '0000-00-00',
`jobId` int(11) default NULL,
PRIMARY KEY (`subjobId`),
KEY `NewIndex` (`jobId`),
FOREIGN KEY (`jobId`) REFERENCES `job` (`jobId`)
) TYPE=InnoDB;
CREATE TABLE `contract` (
`contractId` int(11) NOT NULL auto_increment,
`contractcode` varchar(25) default NULL,
`price` int(11) unsigned default NULL,
`contractprice` int(11) unsigned default NULL,
`company` varchar(50) default NULL,
`signdate` date default '0000-00-00',
`begindate` date default '0000-00-00',
`enddateplan` date default '0000-00-00',
`note` text,
PRIMARY KEY (`contractId`)
) TYPE=InnoDB;
CREATE TABLE `subjob_contract` (
`subjobcontractId` int(11) NOT NULL auto_increment,
`status` varchar(11) default NULL,
`contractId` int(11) default NULL,
`subjobId` int(11) default NULL,
PRIMARY KEY (`subjobcontractId`),
KEY `NewIndex` (`contractId`),
KEY `NewIndex2` (`subjobId`),
FOREIGN KEY (`contractId`) REFERENCES `contract` (`contractId`)
) TYPE=InnoDB
I m using mysql front 3.2 to manage database,I can add first fk but when i add second fk i got an error following this :
sql execution error #1005. response from the database: can't create table'.jobstatus#sql-32c_12f2f.frm' (errno:150). i already define the new index for fk subjobId reference to subjob table what could be the possibility of this error? thank you
Check the datatype and size of the subjobId column on primary table and referenced table. both must be same than it will allow you to create foreign key.
Answer is: You can not refer that column/table which is not created yet. Try to execute tables having foreign keys after the referenced tables.
Obviously you should have consistency in datatypes of foreign key and referenced column as well
Correct Execution Demo. Also You should use Engine=InnoDB instead of Type=InnoDB