Querying two tables... in MySQL - mysql

CREATE TABLE IF NOT EXISTS `document`
(
`intId` int(11) NOT NULL auto_increment,
`chDocumentTitle` varchar(32) default NULL,
`dtLastUpdate` datetime default NULL,
`chUser` varchar(32) default NULL,
`chLink` varchar(256) default NULL,
`Keyword` varchar(256) default NULL,
`intParentid` int(11) NOT NULL,
PRIMARY KEY (`intId`),
KEY `dtLastUpdate` (`dtLastUpdate`,`chUser`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;
CREATE TABLE IF NOT EXISTS `category`
(
`intId` int(11) NOT NULL auto_increment,
`chName` varchar(32) NOT NULL,
`Isactive` tinyint(1) NOT NULL default '0',
`chnestUnder` int(5) NOT NULL default '0',
PRIMARY KEY (`intId`),
KEY `chName` (`chName`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
Now I am looking for a query which will do the following...
Want to list out the documents of the categories... in hierarchical order.
Category One
Documents of Category One
Sub Category - [ If any ]
Documents of Sub Category
Based on this I need to generate XML.

This page has a very good explanation and plenty of helpful examples on how to work with hierarchical data in MySQL. In your situation it's definitely worth the read:
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
...
Also make sure to follow the link to
There's also a reference to this page, with tips on how to work with hierarchical data in your database with a bit of help from PHP.

Related

What should be the Schema for Donation table?

I am creating a web portal for an organization and I am a bit confused on this part.
They will be receiving donations from their registered members as well as guests. I was thinking of creating a users table that is solely used for registered members and no guests etc. because users table will contain unique "email" column and I don't want it to be null.
For donations, I can add user_id foreign key for users table.
What I am thinking of doing is that I should add "name" and "mobile" columns in donations table, so that if it's a guest, we should only get his name and phone number and put in donations table. Do you think this is the right way?
For just demo purpose I am showing you the table:
users table
CREATE TABLE IF NOT EXISTS `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`mobile` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`status` tinyint(1) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`),
UNIQUE KEY `users_mobile_unique` (`mobile`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
donations table
CREATE TABLE IF NOT EXISTS `donations` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned DEFAULT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`mobile` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`status` tinyint(1) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `users_user_id_foreign` (`user_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
Any help would be much appreciated.
Thanks
There are many ways to solve data problems - some better than others. I would not have a separate user table if you are already getting some details. Rather have a REGISTERED_USER column or along those lines to denote a "full user" versus a partial. Then everything stays relatively simple AND the user has an option to become a full user later, which I assume you want for donations... :)

Unable to create table from query

I have the following query
CREATE TABLE grades_gra (
id_gra INT(11) NOT NULL AUTO_INCREMENT,
identifier_gra VARCHAR(2) DEFAULT NULL,
name_gra VARCHAR(250) DEFAULT NULL
PRIMARY KEY (id_gra)
)
ENGINE = INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=UTF8;
When I execute it, it gives me an error invalid default vale for 'naes_gra'
You forgot a comma before primary key:
CREATE TABLE grades_gra (
id_gra INT(11) NOT NULL AUTO_INCREMENT,
identifier_gra VARCHAR(2) DEFAULT NULL,
name_gra VARCHAR(250) DEFAULT NULL,
PRIMARY KEY (id_gra)
)
ENGINE = INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=UTF8;
SQLFiddle demo
Put the comma after DEFAULT NULL, before PRIMARY keyword

Normalizing CSV to MySQL?

I'm new to the whole "normalized table" thing. I have a csv file with the contents as follows:
Cell,Width(m),Length(m),Spacing(m),VDD(V),VSS(V),Temp,Param,Value,Path,TOOL
pmos_var12,5e-03,5e-03,5e-03,0.5,0,0,delay[s],4.65e-06,/home/user/tests/run2/pspice
pmos_var12,5e-03,5e-03,5e-03,0.5,0,10,delay[s],6.2e-06,/home/user/tests/run2/pspice
pmos_var12,5e-03,5e-03,5e-03,0.5,0,25,delay[s],7.46e-06,/home/user/tests/run2/pspice
pmos_var12,5e-03,5e-03,5e-03,0.5,0,70,delay[s],8.98e-06,/home/user/tests/run2/pspice
pmos_var12,5e-03,5e-03,5e-03,0.5,0,100,delay[s],9.56e-06,/home/user/tests/run2/pspice
nmos_var12,5e-03,5e-03,5e-03,0.5,0,0,delay[s],4.65e-06,/home/user/tests/run2/pspice
nmos_var12,5e-03,5e-03,5e-03,0.5,0,10,delay[s],6.2e-06,/home/user/tests/run2/pspice
nmos_var12,5e-03,5e-03,5e-03,0.5,0,25,delay[s],7.46e-06,/home/user/tests/run2/pspice
nmos_var12,5e-03,5e-03,5e-03,0.5,0,70,delay[s],8.98e-06,/home/user/tests/run2/pspice
nmos_var12,5e-03,5e-03,5e-03,0.5,0,100,delay[s],9.56e-06,/home/user/tests/run2/pspice
I've created these tables to store the data:
CREATE TABLE `TEST__RUN_MAPPING` (
`ID` int(11) NOT NULL auto_increment,
`NAME` varchar(45) NOT NULL,
`STATUS` varchar(20) NOT NULL,
`PATH` text NOT NULL,
`TOOL` varchar(10) NOT NULL,
`COMMENTS` text NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TABLE `TEST__DATA_MAPPING` (
`ID` int(11) NOT NULL auto_increment,
`NAME_ID` int(11) NOT NULL,
`CONDITIONS` int(11) NOT NULL,
`VALUE` varchar(10) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TABLE `TEST__CONDITION_MAPPING` (
`ID` int(11) NOT NULL auto_increment,
`CELL_ID` int(11) NOT NULL,
`W_ID` int(11) NOT NULL,
`L_ID` int(11) NOT NULL,
`SPACE_ID` int(11) NOT NULL,
`VDD_ID` int(11) NOT NULL,
`VSS_ID` int(11) NOT NULL,
`TEMP_ID` int(11) NOT NULL,
`PARAM_ID` int(11) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
TEST__RUN_MAPPING ID maps to TEST__DATA_MAPPING NAME_ID
TEST__DATA_MAPPING CONDITIONS maps to TEST__CONDITION_MAPPING ID
All *ID in TEST_CONDITION_MAPPING map to their own table in order to have things unique.
each one of these csv files will differ in what technology used in the simulations, and I keep tabs on this with the NAME column in TEST__RUN_MAPPING. Cell, Width(m), Length(m), Spacing(m), VDD(V), VSS(V), and Temp are all values that are swept, but usually they're the same per technology so I grouped them together in a separate table.
Are there any other ways that a more experienced person could break down the relationship such that it can have optimal reading times? better normalization?
If I understand this structure correctly then I would not seperate the conditions table from the run table. Surely they would have a 1-to-1 relationship. So why not have them both in the same table. The conditions for that paticular run.
Also I would be careful about putting a 'TEXT' block inside a record. TEXT and Blobs can cause some performance problems. varchar in mysql 5 can go as high as 65,000 characters. For paths you should not need more than 1024 characters. So varchar(1024) should be enough for a path.

How do fields not selected for in a MySQL query affect query speed for the fields I am selecting on?

This is a theoretical question based on an application I have. I am wondering if there is some technical insight to be gained beyond just speed tests on my system.
I have the following two tables:
CREATE TABLE `files` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`url` varchar(255) NOT NULL DEFAULT '',
`processed` tinyint(1) unsigned NOT NULL DEFAULT '0',
`last_processed` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `url` (`url`),
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
and...
CREATE TABLE `file_metas` (
`file_id` int(10) unsigned NOT NULL,
`title` varchar(255) NOT NULL DEFAULT '',
`description` varchar(1000) NOT NULL DEFAULT '',
`keywords` varchar(1000) NOT NULL DEFAULT '',
PRIMARY KEY (`file_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
The file_metas data is long text strings about each file from the files table. Each file only has one entry in the file_metas table so these two tables could be combined.
I'm wondering what affect adding the long text fields to the files table will have on the performance of select statements done on the files table when I'm not selecting for title, description, or keywords. I'm curious about the technical details. Does simply having the text fields in the table slow queries not involving those fields? How does this work in general with MySQL MyISAM tables? Is there any good reason to keep the file_metas data in a separate table?

MySQL query: pull all the other categories minus the one that has been saved

I really need some help with forming a MySQL query that I just cannot work out. On my website I have a system in place that will hopefully remember some selections that user made when they last visited the site.
On the site the user can select which category they wish to read the content of next time they come to site. That setting will be remembered but the menu should be displayed slightly different. It should show all the other categories minus the one that has been saved.
So if I have these categories,
Blog
Inspiration
Case Studies
and the user saved Blog, the next time they come to the site the categories list should just be
Inspiration
Case Studies.
How can this data be pulled from the database?
Currently I have a table that identifies the user via a unique cookie id:
CREATE TABLE IF NOT EXISTS `cookieTable` (
`cookieEntryId` int(11) NOT NULL AUTO_INCREMENT,
`cookieId` varchar(32) NOT NULL,
`expirationDate` int(10) NOT NULL,
PRIMARY KEY (`cookieEntryId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
I have a category table
CREATE TABLE IF NOT EXISTS `categoryTable` (
`categoryId` int(11) NOT NULL AUTO_INCREMENT,
`categoryTitle` varchar(25) NOT NULL,
`categoryAbstract` varchar(150) NOT NULL,
`categorySlug` varchar(25) NOT NULL,
`categoryIsSpecial` int(1) DEFAULT NULL,
`categoryOnline` int(1) DEFAULT NULL,
`dashboardUserId` int(11) NOT NULL,
`categoryDateCreated` int(10) NOT NULL,
PRIMARY KEY (`categoryId`),
KEY `dashboardUserId` (`dashboardUserId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
And I have the table that saves what categories the user has saved,
CREATE TABLE IF NOT EXISTS `userMenuTable` (
`menuEntryId` int(11) NOT NULL AUTO_INCREMENT,
`categoryId` int(11) NOT NULL,
`cookieId` varchar(32) NOT NULL,
PRIMARY KEY (`menuEntryId`),
KEY `categoryId` (`categoryId`,`cookieId`),
KEY `cookieId` (`cookieId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6;
The following query should get the categories the user hasn't saved assuming the cookieId stays constant for a user. If it doesn't you should put a userId into the userMenuTable instead. Just replace USERSCOOKIEID with their actual cookie ID.
SELECT * FROM categoryTable WHERE categoryId not in
(SELECT categoryId FROM userMenuTable WHERE cookieId = 'USERSCOOKIEID') as x