How do I create a "link" between two mySQL tables? - php

I have two tables that look as Follows:
Person (Table Name)
Name1/Phone1/Email1/Address1/Organization1/Notes1 (Fields)
Organization (Table Name)
Organization1/Phone2/Email2/Address2/Web2/Notes2 (Fields)
Organization1 is the only field in common between the two tables.
When I display data on a person, I want to also check and see if there is data on their organization and display it as well if it exists. I'm using PHP to interface with mySQL.

You need to JOIN the tables.
SELECT * FROM Person LEFT JOIN Organization ON Person.Organization = Organization.Name;
This assumes the relationship is the Organization Name. I've done a LEFT JOIN since you said if exists. Check out this tutorial for more detail on joining tables.
Note: I agree and would recommend making your database more relational by adding Primary Keys and using them as Foreign Keys in your other tables.

This post is an explanation of relations, not code for you to use. If you want that, look elsewhere
Well, connections between tables are called relations. There are 3 types of relations.
1) One -> One - This type of relation means 1 row is related to 1 other row in a different table
2) One -> Many - This type of relation means 1 row is related to a variable number of rows in a different table.
An example may be A folder can have multiple files, but a file can't have multiple folders. So in this case the 1 would be the folder, and the many would be the files.
3) Many -> Many - This type of relation means many rows can relate to many other rows.
An example may be labels. You can label many things the same name (desk appliance for example), and each thing can have multiple labels (a lamp can have both desk appliance & light labels).
.
So now that you know the different relations, we will go into your question. The relation you are looking at is a one to many, one corporation can have many people, but a person can only have one corporation. I suppose a person could work for multiple people, but that is much more complex (so we'll skip it).
One to many relations are by far the most common, and are pretty easy to do. This is where joins come in (left, right, and inner joins). Tizag has an excellent tutorial on joins here: http://www.tizag.com/sqlTutorial/sqljoin.php.
Hope that helps.

You should use a foreign key, but you need to use the InnoDB storage engine (MyISAM does not support foreign keys yet).

Make your tables look something like this:
Person_ID, Name, Phone, Email, Address, Organisation_ID, Notes (or if you have multiple notes, create a seperate table that maps person_id to a note).
Organisation_ID, Name, Phone, Email, Address, Web, Notes.
Select your person, then if Organisation_ID exists, select the Organisation where Organisation_ID equals the ID you obtained from the person row.

Related

Foreign key vs. SET data type MySQL

I have a MySQL database set up with a list of all my movies, which I imported from a MS Access database. One field contains the possible values for the genre of the movie, movies can have more than one genre, so I need a data type which supports this feature. In access I could link one table 'genre' to the field 'genre' in my table 'movies', so I could choose none, one ore multiple genres per movie. When I switched to MySQL I used the SET data type to define all the possible values. So far everything is running perfectly.
I am now trying to set up a table in html/php to show the mysql table. I want the table to be able to sort on: title, genre, quality, rating, etc. But for the sorting on genre, I would need the possible values from the set data type. I don't know if it is possible to get the values with some php command/code, but after I lurked around on the web for a while, I didn't see many applications where they use the SET data type for obvious negative reasons.
So I started looking into the Foreign Key possibility. The problem I have here is that -for as far as I know- the key can only contain one possible value, which puts me right back at the start of my problem. I do like the idea of a foreign key, because it would make it way easier for me to add a new genre to the list.
Is there a possibility I am overlooking? Is it possible to either get the values from the SET type to php or to use a foreign key with multiple possibilities for one record?
I know I can also put every genre in my php script manually, but I'd like to have it all on one place. So that if I add a movie with a genre I haven't defined yet, I can just update it at one place and everything else adapts to it.
Dagon is absolutely right here - you have an issue with the structure of the tables in your back end. You are wanting to model a many to many relationship when at the moment with your current back end the best you can do is a one to many relationship.
To review:
You have individual films that can have many genres
And you have individual genres that are related to many films
Relational databases actually don't model many to many relationships with one relationship they use recursion of the one to many relationship and create two joins.
To model a many to many relationship you need three tables
A film table (which I think you already have)
A genre table (which I think you already have)
A junction table which as Dagon suggests will consist of two fields film id and genre id.
You then set up two separate one to many relationships. One from the film table to the junction table and one from the genre table to the junction table.
Now if you want to know all the genres a film is in you simply filter the junction table on the relevant film id and if you want to know all the films with a certain genre you filter the junction table on the genre id.
Set up lookups to relate your genre ids to textual descriptions and bang you are free to change the textual description as much as you want and the great thing if you've done it right it will upgrade every single value in your forms.
This is an absolute fundamental concept of the algebra of sets behind the design of SQL and relational database design.

Backend app in OO PHP: Structuring classes/tables efficiently

I'm currently working on an app backend (business directory). Main "actor" is an "Entry", which will have:
- main category
- subcategory
- tags (instead of unlimited sub-levels of division)
I'm pretty new to OOP but I still want to use it here. The database is MySql and I'll be using PDO.
In an attempt to figure out what database table structure should I use in order to support the above classification of entries, I was thinking about a solution that Wordpress uses - establish relationship between an entry and cats/subcats/tags through several tables (terms, taxonomies, relationships). What keeps me from this solution at the moment is the fact that each relationship of any kind is represented by a row in the relationships table. Given 50,000 entries I would have, attaching to a particular entry: main cat, subcat and up to 15 tags might slow down the app (or I am wrong)?
I then learned a bit about Table Data Gateway which seemed an excellent solution because I liked the idea of having one table per a class but then I read there is virtually no way of successful combating the impedence missmatch between the OOP and relational-mapping.
Are there any other approaches that you may see fit for this situation? I think I will be going with:
tblentry
tblcategory
tblsubcategory
tbltag
structure. Relationships would be based on the parent IDs but I+'m wondering is that enough? Can I be using foreign key and cascade delete options here (that is something I am not too familiar with and it seems to me as a more intuitive way of having relationships between the elements in tables)?
having a table where you store the relationship between your table is a good idea, and through indexes and careful thinking you can achieve very fast results.
since each entry must represent a different kind of link between two entities (subcategory to main entry, tag to subcategory) you need at least (and at the very most) three fields:
id1 (or the unique id of the first entity)
linkid (linking to a fourth table where each link is described)
id2 (or the unique id of the second entity)
those three fields can and should be indexed.
now the fourth table to achieve this kind of many-to-many relationship will describe the nature of the link. since many different type of relationship will exist in the table, you can't keep what the type is (child of, tag of, parent of) in the same table.
that fourth table (reference) could look like this:
id nature table1 table2
1 parent of entry tags
2 tag of tags entry
the table 1 field tells you which table the first id refers to, likewise with table2
the id is the number between the two fields in your relationship table. only the id field should be indexed. the nature field is more for the human reader then for joining tables or organizing data

How to model database where different users/roles are in a project table, while all of them have to belong to user table?

I am trying to model a database for my current project and I came across a new problem. I have a Project which is supervised by Supervisor, Coordinator and Company. So Project table has Supervisor.id as foreign key and so on. There is also Student table which contains Project.is as a foreign key (because many users can do a project). This is how it is right now. What I would like to do is to have a User table containing a column named type which allows me to see what the role of that particular user is (also student). Even though the table will contain many NULL entries, I will have far less redundant code.
However, the main reason I want to have one User table is that I am using CakePHP and it is not easy to have different models log in. Is this possible in a nice way?
Thanks
EDIT: Maybe I should say that every one of these roles will have different permissions.
I see three tables: USER, GROUP, and ROLE.
Users would be assigned to groups, and groups given roles. I think you need three, not one.
And cardinality matters: I can see where a USER could be assigned to many GROUPS; a GROUP could have many USERS; a ROLE could be assigned to several GROUPS; and a GROUP could have many ROLES. There are many to many JOIN tables as well:
USER <-> USER_GROUP <-> GROUP <-> GROUP_ROLE <-> ROLE
This is normalized - nothing is repeated this way. USER, GROUP, and ROLE have primary keys. The JOIN table primary key is a composite of the two IDs in each row.
It depend on how you will use your associations.
Why not
For example: if you use relation to output data later and you sure, that you database scheme will not changed, than ... why not? your main targets: quality of code and speed of development, so, not matter how much columns with null you will have.
But
if you not sure in your requirements or plan to extend database scheme you can use two columns
supervisor_model
supervisor_id
which will store apropriate values: Company, 77 (I mean that 77 it's id of come Company )
Another approach
You can UUID for you supervisor_id so, it will be unique among several tables and you have not many NULL and extra columns.

Advice on database design for portfolio website

So I'm a visual designer type guy who has learned a respectable amount of PHP and a little SQL.
I am putting together a personal multimedia portfolio site. I'm using CI and loving it. The problem is I don't know squat about DB design and I keep rewriting (and breaking) my tables. Here is what I need.
I have a table to store the projects:
I want to do fulltext searcheson titles and descriptions so I think this needs to be MyISAM
PROJECTS
id
name (admin-only human readable)
title (headline for visitors to read)
description
date (the date the project was finished)
posted (timestamp when the project was posted)
Then I need tags:
I think I've figured this out. from researching.
TAGS
tag_id
tag_name
PROJECT_TAGS
project_id (foreign key PROJECTS TABLE)
tag_id (foreign key TAGS TABLE)
Here is the problem I have FOUR media types; Photo Albums, Flash Apps, Print Pieces, and Website Designs. no project can be of two types because (with one exception) they all require different logic to be displayed in the view. I am not sure whether to put the media type in the project table and join directly to the types table or use an intermediate table to define the relationships like the tags. I also thinking about parent-types/sub-types i.e.; Blogs, Projects - Flash, Projects - Web. I would really appreciate some direction.
Also maybe some help on how to efficiently query for the projects with the given solution.
The first think to address is your database engine, MyISAM. The database engine is how MySQL stores the data. For more information regarding MyISAM you can view: http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html. If you want to have referential integrity (which is recommended), you want your database engine to be InnoDB (http://dev.mysql.com/doc/refman/5.0/en/innodb-storage-engine.html). InnoDB allows you to create foreign keys and enforce that foreign key relationship (I found out the hard way the MyISAM does not). MyISAM is the default engine for MySQL databases. If you are using phpMyAdmin (which is a highly recommended tool for MySQL and PHP development), you can easily change the engine type of the database (See: http://www.electrictoolbox.com/mysql-change-table-storage-engine/).
With that said, searches or queries can be done in both MyISAM and InnoDB database engines. You can also index the columns to make search queries (SELECT statements) faster, but the trade off will be that INSERT statements will take longer. If you database is not huge (i.e. millions of records), you shouldn't see a noticeable difference though.
In terms of your design, there are several things to address. The first thing to understand is an entity relationship diagram or an ERD. This is a diagram of your tables and their corresponding relationships.
There are several types of relationships that can exist: a one-to-one relationship, a one-to-many relationship, a many-to-many relationship, and a hierarchical or recursive relationship . A many-to-many relationship is the most complicated and cannot be produced directly within the database and must be resolved with an intermittent table (I will explain further with an example).
A one-to-one relationship is straightforward. An example of this is if you have an employee table with a list of all employees and a salary table with a list of all salaries. One employee can only have one salary and one salary can only belong to one employee.
With that being said, another element to add to the mix is cardinality. Cardinality refers to whether or not the relationship may exist or must exist. In the previous example of an employee, there has to be a relationship between the salary and the employee (or else the employee may not be paid). This the relationship is read as, an employee must have one and only one salary and a salary may or may not have one and only one employee (as a salary can exist without belonging to an employee).
The phrases "one and only one" refers to it being a one-to-one relationship. The phrases "must" and "may or may not" referring to a relationship requiring to exist or not being required. This translates into the design as my foreign key of salary id in the employee table cannot be null and in the salary table there is no foreign key referencing the employee.
EMPLOYEE
id PRIMARY KEY
name VARCHAR(100)
salary_id NOT NULL UNIQUE
SALARY
id PRIMARY KEY
amount INTEGER NOT NULL
The one-to-many relationship is defined as the potential of having more than one. For example, relating to your portfolio, a client may have one or more projects. Thus the foreign key field in the projects table client_id cannot be unique as it may be repeated.
The many-to-many relationship is defined where more than one can both ways. For example, as you have correctly shown, projects may have one or more tags and tags may assigned to one or more projects. Thus, you need the PROJECT_TAGS table to resolve that many-to-many.
In regards to addressing your question directly, you will want to create a separate media type table and if any potential exists whatsoever where a project is can be associated to multiple types, you would want to have an intermittent table and could add a field to the project_media_type table called primary_type which would allow you to distinguish the project type as primarily that media type although it could fall under other categories if you were to filter by category.
This brings me to recursive relationships. Because you have the potential to have a recursive relationship or media_types you will want to add a field called parent_id. You would add a foreign key index to parent_id referencing the id of the media_type table. It must allow nulls as all of your top level parent media_types will have a null value for parent_id. Thus to select all parent media_types you could use:
SELECT * FROM media_type WHERE parent_id IS NULL
Then, to get the children you loop through each of the parents and could use the following query:
SELECT * FROM media_type WHERE parent_id = {$media_type_row->id}
This would need to be in a recursive function so you loop until there are no more children. An example of this using PHP related to hierarchical categories can be viewed at recursive function category database.
I hope this helps and know it's a lot but essentially, I tried to highlight a whole semester of database design and modeling. If you need any more information, I can attach an example ERD as well.
Another posibble idea is to add columns to projects table that would satisfy all media types needs and then while editting data you will use only certain columns needed for given media type.
That would be more database efficient (less joins).
If your media types are not very different in columns you need I would choose that aproach.
If they differ a lot, I would choose #cosmicsafari recommendation.
Why don't you take whats common to all and put that in a table & have the specific stuff in tables themelves, that way you can search through all the titles & descriptions in one.
Basic Table
- ID int
- Name varchar()
- Title varchar()
etc
Blogs
-ID int (just an auto_increment key)
-basicID int (this matches the id of the item in the basic table)
etc
Have one for each media type. That way you can do a search on all the descriptions & titles at the one time and load the appropriate data when the person clicked through the link from a search page. (I assume thats the sort of functionality you mean when you say you want to be able to let people search.)

Querying multiple tables MySQL

I use MySQL and trying to write a PHP script for my school project.
There is one table named lessons contains this columns:
-id
-lessonid.
-studentid
I also have two different tables for notes and announcements
announcements and notes tables contains these columns:
-id
-lessonid
-content
-createdtime
I need to order both announcements and notes from latest to oldest by createdtime but also need to show all lessons a student takes.
For example: A students takes maths and physics lessons. I need to display him/her both notes and announcements for both of physics and maths and all items should be ordered by date. (like a timeline.) And of course I will not show him/her the notes and announcements for chemistry lesson. Also it will be good if I can say it is note or announcement on the list.
Can you help me to write SQL and PHP code for that?
Thanks.
EDIT: This is where I have stuck:
I have combined two tables and ordered them by date. But can't combine them with the lessons a student take.
SELECT title, created, lessonid FROM (SELECT title, created, lessonid FROM notes UNION SELECT title, created, lessonid FROM announcements) as a ORDER BY created DESC
First of all, thanks for letting us know that this is for a school project - therefore I won't give you the answer. If it is in the project then your teacher should have given you the concepts to come up with a solution.
Your question is well put together and I can see how to solve it but ... It's your project so you need to have a crack at it and post what you come up with.
I will give you some hints to get you started.
You need a query to combine the announcements and notes table. Then you need to group the data by the lesson and join that to the students. This is all basic SQL.
Good luck. Post what you come up with.
I'll also, follow fellow posters advice, and not do the legwork for you. but won't let you go empty handed, so will give you the concept.
there is a thing called third normal form, we decide how many tables according to that concept, so if its a big database then separate table for first name and separate for last name, as many people share those among themselves, so saves space and redundancy etc. so one table for person has personid as primary, and has lastname foreign key to refer to last name table , we generally name it lastNameRef, similarly firstNameRef. so now, each person has lot of classes, and each class has lot of persons(students) in it. so this is a many-many relation - we create a allreference table to solve this many to many problem. so there is one table for classes which has class id as primary key, so now u create a all reference table which a recordId as primarykey, (just for namesake) and personRef(refers to personId in person table) and classref(refers to classId in class table) if one person has two classes, another entry with same personId but different class Id, at the end, you can query the name of person from person table, and name of class from class table and create join on their foreign keys but use all three tables, result is (JOHN MATH, JOHN SCIENCE) etc, same way you display all notes for john searching name in person table, and subject in class table,and notes in notes table

Categories