Table Associations with multiple id's in one field in CakePHP - php

I am using CakePHP and I have 2 tables, Documents and Download, on the Download table I have a field: Document_id, making the association with the model works fine, but sometimes i have in Document_id a field like this "2,10,12", How can I associat the tables?

You shouldn't store multiple ids in one field (unless you're intentionally denormalizing your database, but then you wouldn't be asking this question).
The "proper" way to do this is use a 3rd table called a linking table. e.g. "documents_downloads", to store the download_ids with matching document_ids.
Download hasMany DocumentDownload
DocumentDownload belongsTo Download & Document
Document hasMany DocumentDownload
The simplest way to implement this is using Cake's "hasMany through (The Join Model)"
See section of the Cakebook:
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasmany-through-the-join-model

Related

How to create a link between the attributes of two tables?

I am creating a database that allows me to save the data to a json online.
I have problems connecting the teams between two tables, the table structure Fixture is as follows:
Table Design teams:
My problem is that I want to load the Fixtures of a given team, for example, I want to load the fixtures of Wolfsburg. Now I'm thinking of being able to exploit the attribute CODE in its teams table, but I do not have this attribute in the table Fixtures and would not know how to connect it as the Fixtures are downloaded from a JSON as you see in the image.
The json presents a link between the team's fixture but concerns the relative links to each team and not a foreign key.
How can I overcome this problem?
Your tables only has homeTeamName and name as common value. You can try to do join on them, but it will be slow and not reliable. I don't see any other way as there is no ID in each table.

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

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

Difference between HABTM relationship and 2 $belongsTo relationship with a third model

I'm creating a project management system which projects are assigned to users
What's the difference between creating a Model ProjectsUser and defining 2 $belongsTo relationship and defining HABTM relationships in both Project and User models? What would be the most correct way, though? And how do I save the data in the projects_users table?
From my experience, if you want to be able to save or delete rows only from the join table (the one with 2 IDs), then it is much more simple using three models associated through both a hasMany and a belongsTo association.
You can also retrieve data from the join table directly and do the queries you want much more easily
This is what CakePHP documentation says refering to HABTM and saving data:
However, in most cases it’s easier to make a model for the join table and setup hasMany, belongsTo associations as shown in example above instead of using HABTM association.
Here you can find more the full text:
http://book.cakephp.org/2.0/en/models/saving-your-data.html#what-to-do-when-habtm-becomes-complicated
I have used this method for a "reads" table (with post_id and user_id) as well as for subscriptions and similar kind of relationships.
The first way is called "hasAndBelongsToMany" [details here].
The second is called "hasMany through" [details here].
The second link relating to "hasMany through" has details and a lengthy explanation about when and why you would want to use it.
Not sure about the specifics of cakephp, but in general defining the relation model explicitly gives you more control over it, for instance if you wanted to do some validation or add callbacks on creation of this relationship.

CakePHP how to use static values (categories)

I would like to have categories, and rankings for my content and users respectively, and I am not sure how to go about implementing this using CakePHP conventions?
Do I need to create a model?
That depends entirely on what these categories are supposed to do and not do. You could simply define a number of constants that you use for categorizing stuff. But, are categories...
subject to change? Do you want to add more eventually?
editable? May you want to change their names?
nested?
supposed to have more attributes than just their id? Names, descriptions?
If you answered Yes to any of the above, you'll want to store them as data in the database. This is independent of Cake, it's just sane data modeling. For Cake that means you'll need to create a model. The same goes for ratings.
So you'll have these tables:
users
hasMany ratings
categories
hasMany contents
contents
belongsTo categories
hasMany ratings
ratings
belongsTo users (polymorphic)
belongsTo contents (polymorphic)
You may want to separate user ratings and content ratings into two tables instead of using a combined polymorphic table (which just means that you have an extra column keeping track of whether a rating is for a user or for content).
i guess you are looking for something like this IF you dont want to use a model:
http://www.dereuromark.de/2010/06/24/static-enums-or-semihardcoded-attributes/
one possible approach to use "enums" for things that maybe only have 1-5 states.
if you have more than 10 or you want to be able to dynamically modify them (label, active/inactive) you will need a separate table and model relation.

Categories