I just would like to know what are the most common approaches to get a table to hold a reference to IDs from multiple tables.
I have a system with modules like customers, suppliers, orders, etc. and I would like to add a "Notes" functionality to all of those modules to be able to add/read notes.
As one customer/supplier/order can have multiple notes, I have chosen the one-to-many relation way and so the notes in their table should refer to the particular item id in a separate column.
But as I will refer to IDs from multiple tables, their IDs will be overlapping and I need a way to say in which particular table to search for that ID.
I don't want to create exact the same notes module for each of my modules and here I could concentrate notes in one table. Those notes differ only in the fact, to which module they belong to.
Shall I
store the particular table name in the notes table? But that name can
change later and the system will break
introduce something like UNIQUE ID or a hash to all of my modules,
which would be unique among different tables and store it's id in
the notes table?
create separate notes table for every module and don't worry about
code/class/table duplication?
Thanks for your ideas!
We do something similar with notes that can be attached to many objects. Each of our objects has a unique class id (we store each type of object in it's own table), and we store the unique class id + specific object id in the notes table.
We then just have to maintain a lookup of unique class id -> table name. By using the unique class id + object id as the key we ensure that the same id in different tables isn't an issue.
Related
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.
I want to create a posting system to a profile. I created a database for storing all users posts each user have a table.
Ihad created another database for storing the comments of each posts. My logic is to create each table in the comments database and store each comment in that.
Is there a logic to link the post and the comments. I thought to use mysql last insert id but it will return last id which will create error because one of the post will not have a table.
Is there any other way?
Another way would be to have a single table for posts, and identify a user post in the table using a userid column. To find all posts by a particular user, simply query by the user's ID. By doing so, you have a single table to manage, and you can do a lookup easily. If you create separate tables for each user, you have to create additional logic to first figure out which table to use. If a user is removed, you delete a table, rather than simply removing some rows from a common table.
The same logic applies to the comments table - add columns for postid',commentid,userid`. Again, a single table contains all the comments. To find comments on a particular post, you would do a simple query such as
select comment_text
from comments_table
where postid = ?
The whole purpose of using MySQL is to leverage relationships between entities, i.e. a user owns posts, a post is linked to comments.
If you do not want to use a relational schema like this, take a look at NoSQL DBs.
You have a couple options here:
Add a user_id column to your posts table, and a post_id, and user_id column to your comments table. You can then setup foreign keys with one-to-many relationships.
Only use a single table that has (in addition to your existing) a user_id, and type column. Type will define comment/post/etc. This can be defined with intermediary tables as a number mapped to a CONST, string, or any other way that you see fit (intermediary best option imho).
Vary the above example and use 2 intermediary tables to match users to posts and comments to posts (possibly also users to comments).
I am working on a game where the user can register, has an inventory and has weapons in that inventory. I want to store this information in my database.
Here is how I have set it up so far:
My user table contains a UserID column (along with other information).
My inventory table contains an InventoryID column and a UserID column
(the UserID corresponds to the owner of the inventory)
My Weapons table contains an InventoryID column which references the
Inventory it belongs to.
Is this the standard way of doing things? Can I change my layout and make it simpler? It just seems a little tedious to work with databases like this.
It would be so much easier if my User table had a reference to an inventory entry and that entry had an array of weapons. I've achieved this by storing references to the ID's of each entry but I can't just create a "User" php class (which has a reference to an Inventory object, which has an array of Weapon objects) by running one query to the database.
Maybe there is a framework to achieve this?
What You described is simple one-to-many relationship.
You don't need inventory table.
You need a user table with userID as primary key and use it as a foreign key in weapons table.
With help of joins You can use one query to get all records.
Have you considered a NoSQL database? :)
Relational databases often require "join" tables as you describe. You can probably accomplish this without a join table if user to inventory is 1:1 - and 1 weapon can only belong to 1 inventory/user - just have weapons store a user ID.
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.)
Lets take the example from Yelp: http://www.yelp.com/boston
You can see that it's a website with several different categories, each category containing a listing of places. Should I include all the different places/listing in a single table, or let each category have its own tables?
EDIT: this means having tables 'places_restaurants' and 'places_nightlife', instead of just having the single table 'places' and every entry of every different category will be stored in one huge table... Will this affect performance?
One table per category will require that you CREATE a table every time there's a new category. I'd prefer CATEGORY and PLACE tables, with a one-to-many or many-to-many relationship between them.
You should keep all of the categories in the same table and then have a CategoryID which actually maps each category to the specific / desired category. Your application should be built in a way that is inherently extensible which creating tables each time is definitely not.
It depends. You could normalize the database so that all categories are in their own table, and only referred to from other tables by a foreign key. But there are some arguments that performance outweighs normalization, and so it may be beneficial to keep category names both in their own table of record, and also to include a category name column in other, frequently-joined tables.
If you took the second approach, you would need to ensure data integrity by implementing UPDATE and DELETE triggers such that whenever a category changes in the table of record (presumably, not often), that other tables containing copies of category names also get updated.
It still depends on the application ,also, all the categories is a many to many fields with a main table and of course beliving u have some unique columns in each table