I have 4 tables related like so
+-----------+ +------------+ +---------+ +----------+
| Project | | Slide | | Shape | | Points |
+-----------+ +------------+ +---------+ +----------+
| id | | id | | id | | id |
+-----------+ | project_id | |slide_id | | shape_id |
+------------+ +---------+ | x |
| y |
+----------+
From the ORM docs I have been reading for the Active record object built into CodeIgniter is it best to keep the tables structured like so or change them to one of the following ways.
First would be to use a total relational table like this
+-----------+ +------------+ +---------+ +----------+ +-------------------------------+
| Projects | | Slides | | Shapes | | Points | | Projects_Slides_Shapes_Points |
+-----------+ +------------+ +---------+ +----------+ +-------------------------------+
| id | | id | | id | | id | | id |
+-----------+ +------------+ +---------+ | x | | Project_id |
| y | | Slide_id |
+----------+ | Shape_id |
| Point_id )
+-------------------------------+
That way everything is related by one table or should I relate things with seperate tables so instead of the above it the relation tables would look like so.
+-----------------+ +---------------+ +---------------+
| Projects_Slides | | Slides_Shapes | | Shapes_Points |
+-----------------+ +---------------+ +---------------+
| id | | id | | id |
| Project_id | | Slide_id | | Shape_id |
| Slide_id | | Shape_id | | Point_id |
+-----------------+ +---------------+ +---------------+
The first way will have a smaller number of entries but less queries to build the ORM object on the other hand the other has less entries and more queries. I really don't know which is best or which an ORM prefers. Or if an ORM can handle one or the other.
Or for an ORM can I keep them like they are and I am misunderstanding the docs.
Thanks for the advice.
You should first determine what kind of relationships you're going to have between the four different object you have defined.
For example, there is no need to create a "Projects_Slides" table unless you have a many-to-many relationship between "Project" and "Slides". As it is, I assume that you would like each Project to have many slides, and each slide to be associated with only one Project? In this case, you have a one-to-many relationship and the first schema would be best.
If you were to define that a Slide could belong to more than one Project, then that would be a many-to-many relationship and the "Projects_Slides" table would make sense.
Did you intend for the Shapes table to be self referential (it has id and shape_id columns)?
Generally, ORM's are happiest when you properly normalize your database. I'd say your first example is the most properly normalized, if you're trying to do what I think you are.
Related
I'm rewriting an old application and I'm using Eloquent to handle the db layer.
I have these two tables:
+----------------+
| core_users |
| |
| id name |
|----------------|
| 1 John Doe |
| 2 Jane Doe |
+----------------+
+---------------------+
| core_access |
| |
| id user_id access |
|---------------------|
| 1 1 users |
| |
| 2 1 stores |
| |
| 3 2 stores |
+---------------------+
This is a belongsToMany relation since a user can have many access roles and access roles can belong to many users. But the core_access table is not a true pivot table, which have proven cumbersome when I wan't to attach and detach access roles to users.
An alternative, that I hesitate from doing, is to alter the table structure with a true pivot table like this:
+------------------------+
| core_user_core_access |
| |
| id user_id access_id |
|------------------------|
| 1 1 1 |
| |
| 2 1 2 |
| |
| 3 2 2 |
+------------------------+
But rather is there a way to setup the current table structure with Eloquent Models with a belongsToMany approach?
For an university project I need to do the following:
Let the user enter ingredients via HTML form, process it via PHP into my MySQL database. For Example:
The user enters EGG and QUANTITY and CALORIES.
Let the user make recipes out of these ingredients. So another form with recipename and ingredients.
Now my question is: How can I connect these tables in a proper manner? So that tablerecipe with recipename knows repiceid 1 consists of 3 eggs, 100g beef and 300g cheese?
I read about lookup tables, but I don't understand them. Any help would be appreciated.
My table structure looks like this so far:
If each recipe will have multiple ingredients, and each ingredient will belong to only one recipe, then you have a One-to-Many relationship. You should define your tables like this:
+----------------+ +------------------+
| recipes | | ingredients |
+----------------+ +------------------+
| recipe_id <----------------+ | ingredient_id |
| recipe_name | | | ingredient_name |
| | +----------------+ recipe_id |
| | | |
| | | |
| | | |
| | | |
| | | |
+----------------+ +------------------+
Notice how the ingredients table has a recipe_id that points to a recipe in the recipes table. When you want to query all the ingredients that belong to a recipe, you could query it like this:
SELECT
*
FROM
recipes r
INNER JOIN ingredients i WHERE i.recipe_id = r.recipe_id
However, this is probably not what you want because you might want to use an ingredient more than once. In this case, each ingredient can belong to more than one recipe and each recipe can have more than one ingredient. This is a Many-to-Many relationship. You should define your tables like this:
+----------------+ +------------------+
| recipes | | ingredients |
+----------------+ +------------------+
| recipe_id <---+ +--> ingredient_id |
| recipe_name | | | | ingredient_name |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
+----------------+ | | +------------------+
| |
| +--------------------+ |
| | recipe_ingredients | |
| +--------------------+ |
| | id | |
+--+ recipe_id | |
| ingredient_id +--+
| quantity |
| type |
| |
| |
| |
| |
+--------------------+
Notice the extra table. This is sometimes called a bridge table and it associates a recipe_id with an ingredient_id. In this way, more than one ingredient can be associated with a recipe, and more than one recipe can be associated with an ingredient. I also added two extra columns to the bridge table that adds more information to the relationship. I added a quantity which is the amount of that ingredient to use, and a type which can be used to define the type of measurement (i.e. cups, grams, teaspoons, etc). When you want to query all the ingredients that belong to a recipe in this case, you could query it like this:
SELECT
*
FROM
recipes r
INNER JOIN ingredients_recipes ir ON ir.recipe_id=r.recipe_id
INNER JOIN ingredients i ON i.ingredient_id=ir.ingredient_id
I have a question about a Junction table in MySQL.
In my Junction Table, I store EmployerID, which references my Employer Table and MeetingID, which references my Meetings Table.
Currently, my Junction table looks like this:
+------------+------------+
| EmployerID | MeetingID |
+------------+------------+
| Employer1 | Meeting1 |
| Employer2 | Meeting1 |
| Employer1 | Meeting2 |
| Employer2 | Meeting2 |
| Employer1 | Meeting3 |
| Employer2 | Meeting3 |
| Employer1 | Meeting4 |
| Emokoyer2 | Meeting4 |
+------------+------------+
However, based on my data I know that e.g. Employer1 attended only Meeting1 and Meeting4 and Employer2 attended only Meeting3 and Meeting4. However, because I have 4 meetings in total in my Meetings table, the junction table lists all EmployersID for all MeetingsID,
Is there a way to correct the Junction table, so that it will correctly display what meetings each employer attended?
So, i have three tables
Table: Users
_________________
| id | user |
-------------------
| 1 | Roy |
| 2 | Ben |
|________|________|
Table: Hability_lists // Where i set the list with all habilities available
___________________________________
| id | category | subcategory |
------------------------------------
| 1 | Programmer | PHP |
| 2 | Programmer | ASP |
|________|____________|_____________|
Table: Habilities // Where i set the habilities from all users
________________________________________
| id | user_id | hability_list_id |
-----------------------------------------
| 1 | 2 | 1 |
| 2 | 1 | 2 |
|________|____________|__________________|
By this, we can see that:
Roy are a ASP Programmer and Ben are a PHP Programmer
But, how to set relative models like this using CakePHP?
I know how by using two models but not using three models.
There is some way to do this? Or maybe a better way to do?
Thanks in advance.
When working with an MVC framework it's highly recommended to follow its conventions. So a few changes may be beneficial for you.
What you are looking for its the HABTM (Has And Belongs To Many) association between the "users" table and the "habilities" table *. I'm guessing, by the design of your table, that a user can have multiple habilities, otherwise you should check the hasMany association.
It should be something like this:
Table habilities:
select * from habilities;
+----+------------+----------------------+----------+
| id | category | subcategoy | created | modified |
+----+------------+------------+---------+----------+
| 1 | Programmer | ASP | | |
| 2 | Programmer | PHP | | |
| 3 | Musician | Classical | | |
+----+------------+------------+---------+----------+
Table users:
select * from users;
+----+-------+---------------------+---------------------+
| id | name | created | modified | **
+----+-------+---------------------+---------------------+
| 1 | Roy | 2012-08-15 02:52:18 | 2013-01-17 03:25:28 |
| 2 | Ben | 2012-11-10 03:36:12 | 2012-11-10 03:36:12 |
+----+-------+---------------------+---------------------+
Relational table for HABTM:
select * from habilities_users;
+----+-------------+-------------------+----------+
| id | hability_id | user_id | created | modified |
+----+-------------+---------+---------+----------+
| 1 | 1 | 2 | | |
| 2 | 2 | 1 | | |
+----+-------------+---------+---------+----------+
Look the reference columns in habilities_users, they're singular with a _id suffix to work with CakePHP.
Defining the models classes it's also important, since it's where you define all their associations.
app/Model/User.php
<?php
class User extends AppModel {
public $hasAndBelongsToMany = array('Hability');
}
app/Model/Hability.php
<?php
class Hability extends AppModel {
public $hasAndBelongsToMany = array('User');
}
The table habilities_users doesn't need a model file, its behaviours and properties are implicit in the declaration of its associated models.
* using those names it's also the CakePHP way. [link]
** adding "created" and "modified" in each table will store those events for each record automatically.
You'll want to use HasAndBelongsToMany (HABTM).
This allows you to have two models - User and Hability that are joined by a "tweener" table.
I have 14 tables (one for every year) with product code, firm name and invoice numbers. Main structure of table is identical (product code, ID), but there can be some variables in names of firms.
Table2011
| ID | productcode | firm1 | firm2 | firm3 | etc |
| 1 | G-00001 | 2;5;40| 32;67 | | 150 |
| 2 | G-00005 | | 50 | | |
|etc | | | | | |
Table2010
| ID | productcode | firm1 | firm2 | firm3 |etc |
| 1 | G-00001 | 1;10 | | 55 | |
| 2 | G-00003 | | 2 | | |
| 3 | G-00005 | | 50 | 40 | |
| etc| | | | | |
Table2009
...
Column Firm1 do not usually equals to same firm as firm 1 in other table
I am using table editor to work with tables (adding columns to table, editing values…).
I would like to know if it is possible to achieve result like below. It is above my PHP skills.
Product G-00001 page
…
<UL>
<LI>Year 2011: 150etc; 67firm2; 40firm1; 32firm2; 5firm1; 2firm1</LI>
<LI>Year 2010: 55firm3; 10firm1; 1firm1</LI>
<LI>Year 2009: ...</LI>
...
</UL>
…
Lemme begin with book recommendation : SQL Antipatterns. You will need it, doesn't matter if you caused this mess or ar just assigned to fix it.
If i was in your place, first thing would do would be to fix the database structure. This is madness. You do not need a new table for each year and new column for each company. Database is not a form of Excel spreadsheet.
Invoices Years Companies
----------------- ------------- ---------------
| product_code PK | | year_id PK | | company_id PK |
| company_id FK | | number | | title |
| amount | ------------- ---------------
| year_id FK |
-----------------
Where PK - primary key and FK - foreign key.
This structure would make the gathering of information much much much MUCH easier.
If you just want to display the data and not worry about the restructuring just yet you can use a JOIN to display the information from all the tables.
Although I would agree with teresko you really need to redesign that database. It is not maintainable the way it is.