php/mysql special tree - php

I was messing arround with code and i can't figure out to do this:
I have a Table in the database like this:
CREATE TABLE IF NOT EXISTS `nodetree` (
`node` int(11) NOT NULL,
`prevnode` int(11) NOT NULL,
`nextnode` int(11) NOT NULL,
`nodename` varchar(30) NOT NULL,
`nodelink` varchar(255) NOT NULL,
PRIMARY KEY (`node`,`prevnode`, `nextnode`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
What i want to do is to get php build that graph automatically with tables. Each node is a clickable link to node description.
Thanks in advance.

By definition a node in a tree can only have one parent. But that isn't the case in your example. What you really have here is a directed graph, not a tree. You might want to have a look at this link for a good example of how to represent and query a graph in SQL.

Related

How to store resume details in MySql database

I am developing a website (using PHP,MySQL) that deals with resumes of job-seekers. So the database should hold data like education details, projects, skills, etc. I have created different tables for them like shown below.
Basic info table
CREATE TABLE IF NOT EXISTS `candidates` (
`candId` bigint(20) NOT NULL,
`firstName` varchar(255) NOT NULL,
`lastName` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`contact` char(10) NOT NULL,
`address` text NOT NULL,
`gender` char(1) NOT NULL,
)
Experience table
CREATE TABLE IF NOT EXISTS `Experience` (
`candId` bigint(20) NOT NULL,
`companyName` varchar(255) NOT NULL,
`duration` varchar(20) NOT NULL,
`jobRole` varchar(255) NOT NULL,
`workType` varchar(50) NOT NULL
)
Like this,i have created tables for master degree(course,percentage),bachelors degree(course,percentage),skills(name,efficiency),achievements,etc.
In a page,i want to display all the information.For that 10 tables should be accessed in the page.I know that will load the page slowly.Are there any better ways to implement it?
What you need to do is use indexes, foreign keys and MySQL JOIN to achieve the performance.
So Table which have candId should be referenced from main candidates table using foreign keys.
Now when you fetch candidates's all details, use single query using JOIN to get all the candidate's related data. This will help you to improve performance issue.

Dynamically update sql columns based on number of entries

I want to create a table like below:
id| timestamp | neighbour1_id | neighbour1_email | neighbour2_id | neighbour2_email
and so on upto max neighbour 20.
I have two questions:
Should I create columns statically or is there a way to create columns dynamically using php based on the count of json Array?
In either case, how would I refer to the columns dynamically and assign value to them based on jsonArray?
My jsonArray would look something like:
{id:123, email_id:abc, neighbours: [{neighbour1_id:234, neighbour1_email: bcd}, {neighbour2_id:345, neighbour2_email:dsf}, {}, {}...]}
Please advice. Thanks.
It looks like you need to rethink your database structure a bit. To me it looks like you need a single users (or whatever they are) table:
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(255) NOT NULL,
`cretaed_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
);
And another table that defines relations between those users:
CREATE TABLE `neighbors` (
`parent` int(11) unsigned NOT NULL,
`child` int(11) unsigned NOT NULL,
PRIMARY KEY (`parent`,`child`)
);
Now you can add as many neighbors to each user as you want. Fetching them is as easy as:
SELECT * FROM `users`
LEFT JOIN `neighbors` ON `users`.`id` = `neighbors`.`child`
WHERE `neighbors`.`parent` = ?
Where that question mark would become the id of the user from which you are fetching the neighbors, preferably by using a prepared statement.
If it is all JSON you will be working with, and querying isn't much of an issue, you could consider working with a noSql database or document store (like redis or mongoDb), but that is an entirely different story.
Just repeating a bunch of columns x times is definitely not the way to go. Vertical size (# rows) of tables in relational databases is no big issue, they are designed for that. Horizontal size (# columns) however is something to be careful with, as it may make your db uanessacry large, and decrease performance.
Just consider what you would if you want to find a user that has a neighbor with an email address [x]. You would have to repeat your where statement 20 times for each possible email column. And that is just one example...
well, the answer i was working on while pevara was posting theirs faster is almost the same...
CREATE TABLE `neighbours` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`neighbour_email` char(64) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
CREATE TABLE `neighbour_email_collections` (
`id` int(10) unsigned NOT NULL,
`email_id` char(64) NOT NULL,
`neighbour_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`,`neighbour_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
insert into neighbours values (234, "bcd");
insert into neighbours values (345, "dsf");
insert into neighbour_email_collections values(123, "abc", 234);
insert into neighbour_email_collections values(123, "abc", 345);
select *
from neighbours
left join neighbour_email_collections
on neighbour_email_collections.neighbour_id=neighbours.id
where neighbour_email_collections.id=123;

Better alternative for comma separated field in mysql

In my application whenever a user upload a wallpaper,i need to crop that wallpaper into
3 different sizes and store all those paths(3 paths for cropped images and 1 for original upload wallpaper) into my database.
I also need to store the tinyurl of the original wallpaper(one which is uploaded by user).
While solving the above described problem i come up with following table structure.
CREATE TABLE `wallpapermaster` (
`wallpaperid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`userid` bigint(20) NOT NULL,
`wallpaperloc` varchar(100) NOT NULL,
`wallpapertitle` varchar(50) NOT NULL,
`wallpaperstatus` tinyint(4) DEFAULT '0' COMMENT '0-Waiting,1-approved,2-disapproved',
`tinyurl` varchar(40) NOT NULL
) ENGINE=MyISAM
wallpaperloc is a comma separated field consisting of original wallpaper location plus locations of all cropped instances.
I know using comma separated field considered to be a bad design in the world of relational database,So Would you like to suggest some other neat and efficient ways?
Use a 1:n relationship between the wallpapermaster and a location table.
Something like this:
CREATE TABLE wallpapermaster (
wallpaperid int unsigned NOT NULL AUTO_INCREMENT,
userid bigint NOT NULL,
wallpaperloc varchar(100) NOT NULL,
wallpapertitle varchar(50) NOT NULL,
wallpaperstatus tinyint DEFAULT '0' COMMENT '0-Waiting,1-approved,2-disapproved',
primary key (wallpaperid)
) ENGINE=InnoDB;
CREATE TABLE wallpaperlocation (
wallpaperid int unsigned NOT NULL,
location varchar(100) NOT NULL,
tinyurl varchar(40),
constraint fk_loc_wp
foreign key (wallpaperid)
references wallpapermaster (wallpaperid),
primary key (wallpaperid, location)
) ENGINE=InnoDB;
The primary key in wallpaperlocation ensures that the same location cannot be inserted twice.
Note that int(10) does not define any datatype constraints. It is merely a hint for client application to indicate how many digits the number has.
Usually you use a fixed location (maybe out of a config), fix extension (usually jpg) and a special filename formats like [name]-1024x768.jpg. This way you only the the name
In my opinion using ; or , in siple application is quite good solution even in relational databases.
You should propably think about amout of splitted images count. If there will be less than 5 wallpapers I would not take overhead complex solutions.
It's easy to maintain in database and application. You will use string splitting/joining methods
No need to adding extra additional tables which you will use join to retreive values.
Using simple varchar rather xml is better because you don't have to rely on application database access engine. When you use ORM or JDBC you have extra additional work to do to handle more complex datatypes.
In more complex systems I would make XML column.
While thumbnails are generated automatically from the single uploaded file, you don't need to store paths to cropped/resized files at all.
Instead you can just use normalized filenames for thumbnails and then find them in filesystem - something that KingCrunch suggested: photo1.jpg, photo1-medium.jpg etc.
Anyway, my 2cc: for avoiding traversing your image library (and created thumbnails) with some harvesters, it's good idea to encrypt name of each thumbnail even with just MD5 + some secret key programmatically, so only your program which knows the key can create proper path to the thumbnails basing on the original name/path. For other clients, naming sequence will be just random.
CREATE TABLE `wallpapermaster` (
`wallpaperid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`userid` bigint(20) NOT NULL,
`wallpapertitle` varchar(50) NOT NULL,
`wallpaperstatus` tinyint(4) DEFAULT '0' COMMENT '0-Waiting,1-approved,2-disapproved',
`tinyurl` varchar(40) NOT NULL
) ENGINE=MyISAM
Create a new table which will create relationship with "wallpapermaster" table
create wallpapermaster_mapper(
`id` unsigned NOT NULL AUTO_INCREMENT,
`wallpapermaster_id` int(10) //this will be foreign key with id of wallpapermaster table
`wallpaper_path1` varchar(100) NOT NULL,
`wallpaper_path2` varchar(100) NOT NULL,
`wallpaper_path3` varchar(100) NOT NULL,
)

Game resources storing

I have the following table townResources in which I store every resource value for every town ID. I am a bit reserved about performance impact for a large amount of users. I am thinking for moving the balance for resources to the towns table, and the general value of an resource to store it in a .php file.
Here you have the townresources table:
CREATE TABLE IF NOT EXISTS `townresources` (
`townResourcesId` int(10) NOT NULL AUTO_INCREMENT,
`userId` int(10) NOT NULL,
`resourceId` int(10) NOT NULL,
`townId` int(10) NOT NULL,
`balance` decimal(8,2) NOT NULL,
`resourceRate` decimal(6,2) NOT NULL,
`lastUpdate` datetime NOT NULL,
PRIMARY KEY (`resourceId`,`townId`,`townResourcesId`,`userId`),
KEY `townResources_userId_users_userId` (`userId`),
KEY `townResources_townId_towns_townId` (`townId`),
KEY `townResourcesId` (`townResourcesId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Stores Town Resources' AUTO_INCREMENT=9 ;
What is the best option in my case?
Your best option is to test first. How much users & towns do you want to support? Triple that.. create the test data and see whether the performance is within bounds.
If you run into trouble with performance you should look into caching the data with redis or memcache.

Save associated data into database with cakephp and HABTM

I have 2 tables: release_servers and release_components
I have a link table release_server_to_components
I right now have it so that each server can have multiple components and that each component can be on multiple servers.
The following are the create statements:
CREATE TABLE `release_components` (
`id` int(11) NOT NULL auto_increment,
`buildID` varchar(45) default NULL,
`svnNumber` varchar(45) NOT NULL,
`componentType` varchar(45) NOT NULL,
`release_id` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM
CREATE TABLE `release_servers` (
`id` int(11) NOT NULL auto_increment,
`server_name` varchar(45) NOT NULL,
`server_environment` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM
Link table:
CREATE TABLE `release_server_to_components` (
`id` int(11) NOT NULL auto_increment,
`release_component_id` int(11) NOT NULL,
`release_server_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM
What I want to add is the ability to have a system ID -- this system ID would be per component on a server (not per server and not per component, but per the component on each server). I want to be able to easily add the system ID per component and insert it into the database.
I can provide code for models and controllers if needed.
You want to "fake" Ruby's through association with CakePHP.
Why do this over HABTM?
Because you want to save data about the association. With Cake's HABTM saving data about the association is difficult, because the only thing you really have is a JOIN table. You need something more powerful than this.
First, get rid of the $hasAndBelongsToMany property in your model. Next we'll be refitting your release_server_to_components table as your "through" table.
So, in ReleaseComponent and ReleaseServer model you would have an association like this:
$hasMany = array('ReleaseServerToComponent');
Now, in your new ReleaseServerToComponent model you would have an association like this:
$belongsTo = array('ReleaseComponent', 'ReleaseServer');
Now, you can access this table just like a normal Cake model, ie $this->ReleaseServer->ReleaseServerToComponent->find(). You can add additional fields to the through table, like server_component_name. You already have a unique identifier for specific, server components with the primary key of the release_server_to_components table.
You could save this data using Cake's saveAll() method. Alternatively you could generate your own data to save, simply plugging in the server ID and component ID from form fields. At the top of that link is the format saved data should be in when you pass it to the model's save method.

Categories