I am a little stuck and need help.
I already have the items table filled with data,
now where I am is stuck is this:
I want to add Tags to the existing urls.
What do i need to do if I have a url and the corresponding tags?
I don't know how the INSERT INTO is with a foreign key.
Any ideas?
I have a MySQL Database like this (Mysqlicious Schema):
CREATE TABLE IF NOT EXISTS `item2tag` (
`item_id` int(10) unsigned NOT NULL,
`tag_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`item_id`,`tag_id`),
KEY `tag_id` (`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `items` (
`vidid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`vidurl` varchar(255) NOT NULL,
`vidimgdir` varchar(255) NOT NULL,
`vidname` varchar(64) NOT NULL,
PRIMARY KEY (`vidid`),
UNIQUE KEY `vidurl` (`vidurl`) )
ENGINE=InnoDB DEFAULT CHARSET=latin1
AUTO_INCREMENT=1782 ;
CREATE TABLE IF NOT EXISTS `tags` (
`tag_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`tag_text` text NOT NULL,
PRIMARY KEY (`tag_id`),
UNIQUE KEY `tag_text` (`tag_text`(255)))
ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Then obtain the id (vidid) of the URL for which you want to add tags.
Now, for each tag, check if it exists already in the tags table. If it doesn't, add it to said table. Then do the following:
INSERT INTO item2tag (item_id, tag_id) VALUES (x, y)
The values should speak for themselves.
Related
I was referring these to Hibernate tuts: 1, 2.
I was not able to understand how one to one and one to many relationships are defined in MySQL tables.
This is SQL for one to many relationship:
CREATE TABLE `Cart` (
`cart_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`total` decimal(10,0) NOT NULL,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`cart_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
CREATE TABLE `Items` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`cart_id` int(11) unsigned NOT NULL,
`item_id` varchar(10) NOT NULL,
`item_total` decimal(10,0) NOT NULL,
`quantity` int(3) NOT NULL,
PRIMARY KEY (`id`),
KEY `cart_id` (`cart_id`),
CONSTRAINT `items_ibfk_1` FOREIGN KEY (`cart_id`) REFERENCES `Cart` (`cart_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
This is SQL for one to one relationship:
-- Create Transaction Table
CREATE TABLE `Transaction` (
`txn_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`txn_date` date NOT NULL,
`txn_total` decimal(10,0) NOT NULL,
PRIMARY KEY (`txn_id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
-- Create Customer table
CREATE TABLE `Customer` (
`txn_id` int(11) unsigned NOT NULL,
`cust_name` varchar(20) NOT NULL DEFAULT '',
`cust_email` varchar(20) DEFAULT NULL,
`cust_address` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`txn_id`),
CONSTRAINT `customer_ibfk_1` FOREIGN KEY (`txn_id`) REFERENCES `Transaction` (`txn_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
If eyes are ok, I dont see any difference between two. Is it like this relationship cardinality constraints are implemented only at hibernate level and are not enforced by database? Or my eyes are missing something?
It's actually possible to define 1:1 relationships in SQL. There are two ways:
The child table has the same PK as the parent table, with the same values. This column is also an FK to the parent table.
The child table has a different PK. It also has a FK that points to the parent table, and this FK has a UNIQUE constraint.
If you noticed, in both cases the FK is UNIQUE (it's the PK, or has a UNIQUE constraint), and that's the key aspect. It's not possible the create a second row in the child table that has the same parent.
The case you included in your question opted for strategy #1.
I have a parent table in MySQL as follows:
CREATE TABLE `parentTBL` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`source_name` varchar(255) DEFAULT NULL,
`loc1` smallint(5) unsigned DEFAULT NULL,
`loc2` smallint(5) unsigned DEFAULT NULL,
`extra_info` json DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1;
a child table:
CREATE TABLE `childTBL` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`source_names_id` int(10) unsigned NOT NULL,
`locations_id` int(10) unsigned NOT NULL,
`extra_info` json DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_childTBL1_idx` (`source_names_id`),
KEY `fk_childTBL2_idx` (`locations_id`),
CONSTRAINT `fk_childTBL1` FOREIGN KEY (`source_names_id`) REFERENCES `source_names` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_childTBL2` FOREIGN KEY (`locations_id`) REFERENCES `locations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
and these 2 tables:
CREATE TABLE `source_names` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`source_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `source_name_UNIQUE` (`source_name`)
) ENGINE=InnoDB AUTO_INCREMENT=85 DEFAULT CHARSET=latin1;
CREATE TABLE `locations` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`loc1` smallint(5) unsigned DEFAULT NULL,
`loc2` smallint(5) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `loc1` (`loc1`,`loc2`)
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=latin1;
I have a trigger for parentTBL table before insert like this:
CREATE DEFINER=`root`#`localhost` TRIGGER `myDB`.`parentTBL_BEFORE_INSERT` BEFORE INSERT ON `parentTBL` FOR EACH ROW
BEGIN
INSERT IGNORE INTO source_names (source_name) VALUES (NEW.source_name);
INSERT IGNORE INTO locations (loc1,loc2) VALUES (NEW.loc1,NEW.loc2);
INSERT IGNORE INTO childTBL (source_names_id,locations_id,extra_info) VALUES (????,????,NEW.extra_info);
END
and I want to insert into childTBL and 2 other tables before inserting into parentTBL but I don't know what should I put in ???? fields in above trigger (third INSERT IGNORE. Move scroll to right)?
(It should be noted that I don't want to use SELECT because I have some millions records and fast insertion is important to me and also my problem is not solved with LAST_INSERT_ID() because it is possible that I need the source_names_id which is added before last_inserted in source_names table.)
At the moment I have one huge tag table and I use mapping table to map tags with another mapping table to map with data table. The reason I added another mapping-to-data table is that I have multiple different data tables.
There are two data tables:
CREATE TABLE IF NOT EXISTS `cars_list` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`description` varchar(255) default NULL,
`photo` varchar(45) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `website_list` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`description` varchar(255) default NULL,
`url` varchar(255) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Both of them I use in my search fields, and they should be linked to one TAG list table
There's tag table:
CREATE TABLE IF NOT EXISTS `tags` (
`tag_id` int(11) NOT NULL auto_increment,
`tag` varchar(255) default NULL,
PRIMARY KEY (`tag_id`),
UNIQUE KEY `tag` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
And what I do - I use two more tables to map data tables with tags:
Two mapping tables:
CREATE TABLE IF NOT EXISTS `tags_map_type` (
`tmtid` int(11) NOT NULL auto_increment,
`type` enum('cars_list','website_list') NOT NULL,
`type_id` int(11) NOT NULL,
PRIMARY KEY (`tmtid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `tags_map` (
`tmid` int(11) NOT NULL auto_increment,
`map_type_id` int(11) NOT NULL,
`tag_id` int(11) NOT NULL,
PRIMARY KEY (`tmid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `tags_map`
ADD CONSTRAINT `tag_id` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`tag_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `map_type_id` FOREIGN KEY (`map_type_id`) REFERENCES `tags_map_type` (`tmtid`) ON DELETE CASCADE ON UPDATE CASCADE;
And table tags_map_type then links either to cars_list or to website_list
QUESTION:
How can I make a foreign key to link tags_map_type to one of the list tables?
Or should I use another mapping table for each cars_list, website_list, some_other_list table?
Which way is correct and best to use?
I have a mysql table whose description is given below
Create Table
CREATE TABLE `question` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`category` varchar(255) DEFAULT NULL,
`is_deleted` bit(1) NOT NULL,
`question` varchar(255) DEFAULT NULL,
`version` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8
I have another table
Create Table
CREATE TABLE `parent_question` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`is_deleted` bit(1) NOT NULL,
`version` int(11) DEFAULT NULL,
`pid` bigint(20) NOT NULL,
`qid` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK8FEA83DBE860AF9` (`pid`),
KEY `FK8FEA83DBF34C20F6` (`qid`),
CONSTRAINT `FK8FEA83DBE860AF9` FOREIGN KEY (`pid`) REFERENCES `parent` (`id`),
CONSTRAINT `FK8FEA83DBF34C20F6` FOREIGN KEY (`qid`) REFERENCES `question` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8
I have the right to insert one row in the question table.So when I add a new row then id will be generated (because it is auto_increment) and I want to store this id in the qid field parent_question table.
Can anybody please tell me how to do it?
Use the last_insert_id() function:
insert into question values (...);
insert into parent_question values (..., last_insert_id(), ...);
The 2 table structures like the following(generated by sequel pro):
The question table:
CREATE TABLE `question` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(128) NOT NULL DEFAULT '',
`content` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The answer table:
CREATE TABLE `answer` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`question_id` int(11) unsigned NOT NULL,
`content` text NOT NULL,
PRIMARY KEY (`id`),
KEY `question_id` (`question_id`),
CONSTRAINT `answer_ibfk_1` FOREIGN KEY (`question_id`) REFERENCES `question` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Now when I want to insert an answer:
Can I do something like:
INSERT INTO answer(content) JOIN question(title,content) VALUE('Ironman',"favourite characters","Who is your favourite characters in Avanger?");
or Is there a better way to do the similar thing?
The best way to do this is by in some way persisting the question id and using it to insert the answers.
If there is no other way, you could do something like this:
INSERT INTO answer(content, question_id)
VALUES('Ironman', (select id
from question
where title ='favourite characters'
and content = 'Who is your favourite characters in Avanger?'));