0

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.

UglyShark
  • 23
  • 1
  • 4

3 Answers3

0

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.)

cosmicsafari
  • 3,949
  • 11
  • 37
  • 56
0

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.

Somal Somalski
  • 578
  • 1
  • 7
  • 21
0

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.

Community
  • 1
  • 1
jth_92
  • 1,120
  • 9
  • 23
  • Wow, teach a man to fish. Lot to take in there. Some of that I already understood. But I think you have empowered me to make my own decision based on how I will use the info. I was going for a many-to-one relationship between the media types and projects so it sounds like I need to include the Parent_id field in Media Types table and simply add type as a field in the projects table with type or type_id as the foreign key. – UglyShark Feb 18 '13 at 19:27
  • As far as the database engine. I am attracted to the merits of the InnoDB engine but it is my understanding that FULLTEXT indexing is not possible on the InnoDB engine until MySQL version 5.6. I know for certain my server is running 5.4 something. I had considered including only a "keyword search" using the tags but thought it more conventional to give fulltext search capability. – UglyShark Feb 18 '13 at 19:31
  • In regards to FULLTEXT searching, I don't think it would be necessary within your context. Throughout my experience with many databases from eCommerce databases, intranet databases, and portfolio databases FULLTEXT search was never used. I think "keyword search" would be most efficient and all that would be necessary. http://stackoverflow.com/questions/1381186/fulltext-search-with-innodb mentions that difficulties were encountered with MyISAM FULLTEXT search. I'm glad I was able to help. In addition, you can still search the description columns, just not every single word would be indexed. – jth_92 Feb 18 '13 at 20:10