I'm using phpactiverecord for this project, I have this db structure:
Tables: Tickets, Labels
I'm currently using a has_many association for these two tables: "Tickets has many labels", however I need to assign each label to different ticket, which is not possible at the moment without having duplicated rows with different id and ticket_id values.
Any idea on how to achieve this ?
Cheers
You need create additional table
table Label2Tickets (`label_id`, `ticket_id`, PRIMARY KEY (`label_id`, `ticket_id`)
\* there you may store date of create, status and etc *\
`created`, `status`, `user_id` ... )
And update existing AR and create new AR for this table:
Ticket HAS MANY Label2Tickets where Label2Tickets.ticket_id = Tickets.id
Label HAS MANY Label2Tickets where Label2Tickets.label_id = Labels.id
Related
Ok I am new in php development so I did some mistakes, didnt planned my database just started because I was so excited about my first project, SO dont judg me.. :D :D
this is my Primary database
Primary Database
and this is my Movies database,
Movies database
so I created the songs database first and stored the data in it, after that i created the movies database and movie_id is the foreign key of the id of movies database, so there are too many songs to add foreign keys in primary database, I want a php script which can insert the foreign key for me in my primary database,
I created a php script ( actually tried for several hours) but didnt succseeded
I wanted to
get movie_name from songs database
match with the movie_name of movies databse
if both movies matches
insert the id of movies database into the movie_id(foreign key) of song database
<?php
require_once ('../inc/db.php') ?>
<?php
$lang_query = " SELECT * FROM songs";
$query = "UPDATE songs SET movie_id = '$mov_id'";
$lang_run = mysqli_query($conn, $lang_query);
$mov_query = " SELECT * FROM movies";
$mov_run = mysqli_query($conn, $mov_query);
$mov_row = 1;
$lang_row = 1;
while ($mov_row = mysqli_fetch_array($mov_run))
{
$mov_name = $mov_row['movie_name'];
$mov_id = $mov_row['id'];
while ($lang_row = mysqli_fetch_array($lang_run))
{
echo $movie_name = $lang_row['movie_name'];
$movie_id = $lang_row['id'];
if ($movie_name == $mov_name)
{
mysqli_query($conn, "UPDATE songs SET movie_id = '$mov_id' where id = '$movie_id'");
}
}
} ?>
Please Help me, Thanks :)
I think you can do it by running following sql query -
update *songs* inner join *movies* on songs.movie_name=movies.movie_name set songs.movie_id=movie.id
I honestly think that before you worry about trying to add foreign keys based on your current schema, that you really need to revisit the schema and normalize the data. Why have the same movie name and movie slug fields in two tables? Why have movies, songs, singers, actors, categories, etc. all in the same table? These things probably all need their own tables that are related to each other.
When building your database, think in real world terms, because you are likely going to want your application users to be able to interact with the data in the database in a real world sense. To me, you would probably need the following tables at a minimum:
movies
songs
movies_to_songs (join table to express many-to-many relationship)
actors
movies_to_actors (many-to-many)
editors
movies_to_editors (many-to-many)
movie_categories
movies_to_movie_categories (if you want to treat this as many-to-many)
singers
songs_to_singers (many-to-many)
youtube_videos (a separate table where you could store all video data)
Each table would have additional columns (properties) that are specific only to a single entity of the type contained in the table. So, for example a movie table might look like
id (primary key)
name
slug
image
language
release_date
youtube_id (reference to listing on youtube_videos table)
And you might have an actors table like:
id (primary key)
name
... (sex, birthday, etc.)
And a movies_to_actors table that is just two columns with compound primary key (i.e. combinations must be unique)
movie_id (references primary key id in movie table)
actor_id (reference primary key id in actors table)
And so on across your various tables.
Just remember to think about the real world relation of one object to another and the real world properties (columns) for each of those individual objects.
I need a help with a PHP/MySQL issue. I have a table named users and other named relationships.
users
--------------
id (PK)
name
email
etc
relashionships
--------------
id (PK)
id_user (FK to users.id)
id_friend (FK to users.id)
rating
I'm trying to INSERT multiple relationships but I don't want duplicated entries. I want to ignore the current row if the row is duplicated. I can't use the IGNORE statement because the id_user and the id_friend columns aren't unique. A user/friend may have multiple relationship rows.
Any tip?
You can create a unique key on the id_user/id_friend tuple. Neither of them are unique, but their combination is.
See multiple column indexes on the documentation.
Thanks amenadiel, I found that solution here and worked for me!
CREATE UNIQUE INDEX relation ON relationship (id_user, id_friend)
Im building a shop and each product has a unique set of attributes.
the product db looks like this:
products_id, relation_id, product_name, description,
price, glass, shipping, img, cat, subcat, model
Since every product has several (~40) different attributes unique to that product only ive created a second table to store them.
products_id, att_name, att_val, att_head, att_standard, att_order
This works fine, because there will never be two unique rows.
The problem, however, is when i need to modify the attributes content.
using MySQL Workbench i can modify a row using something like
UPDATE product_attributes SET att_val='1500' WHERE products_id='112' AND att_head='threshold'
This however, doesn't seem to work when i update from my php script.
Is there an easy way to modify the table to support updating?
Im well aware of the stupidity not having an unique column.
But im not sure how to make the two tables relate.
Where should i store the unique id of the attributes?
One choice,
add a primary key "auto_incremented" into the product_attributes table...
ALTER TABLE `product_attributes` ADD `id` INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST
This Id is just for CRUD (Create Read Update Delete) task.
The only relation you can have between your two tables is the products_id wich allow you to have few product_attributes for one product
Since 1 product has more than 1 unique attributes that u store in a second table, you should use the ID of the table product and store it in the second table with the attributes.
Hope this is what u need?
Lets say i got two tables in mysql.
1. person (id, name, lastname) - Image
2. someothertable (id, name, lastname, action, quantity) - image
I wanted to ask, if its really bad practice, to update both tables at once? For example if someone updates the last name of Robert Jackson to "Smith" then do 2 queries:
mysql_query("UPDATE person SET lastname = '$lastname' WHERE id = '$id'");
mysql_query("UPDATE someothertable SET lastname = '$lastname' WHERE name = '$name' AND lastname = '$oldlastname'");
Assuming for now, you wont meet 2 same names and surnames (its just an example).
Is it strongly recommended, to join those two tables when displaying data from tables, and change last name only in person table?
I didn't have need to use join before (never had databases big enough), and I just started to wonder if there is another way to do this (than 2 queries). Using join will require some code changing, but i am ready to do it, if its right thing to do.
Using a join is not a function of how big your databases are, it's about normalization and data integrity. The reason you would have lastname in only one table is so that there's no need to worry about keeping values in sync. In your example, if those calls are in a single transaction, then they should stay in sync. Unless one of them is changed somewhere else, or manually in the database.
So an option for you would be to have these tables:
person (id, name, lastname)
someothertable (id, person_id, action, quantity)
Instead of using 2 update, you can use trigger : Tutorial here
One option would be to make someothertable have a foreign key constraint on the lastname field in Person. You could apply an update trigger so it would automatically cascade.
Here is an example below:
Alter table someothertable add constraint foreign key (lastname) references Person (lastname) on delete cascade on update cascade;
A generic version of that can be seen below:
Alter table [table-name] add constraint foreign key (field-in-current-table) references [other-table-name] (field-in-other-table) on delete cascade on update cascade;
This can be applied to any field in any table. You can then set the triggers to be appropriate for you. Here is a reference link.
Have you considered normalization?
Another option would be to assign each person in the Person table a uniqueID (i.e. PersonID). Now in all your other tables you where you reference a person you reference them by the unique id. This adds many advantages:
1) It keeps the data normalized
2) It maintains data integrity
3) No need for updates, triggers, or cascades
4) A change would only be required in one place
Hope this helps. Best of luck!
I'm not even sure if this is possible. I am using Kohana framework(ver 2.3). I have 2 separate databases. One called 'employees' and another called 'tracker'. The databases are used in 2 different websites. I want to eliminate a table in the tracker database called 'csr', which contains identical employee data, and link the tracker to the employee info in the employees database.
In my tracker application I have a model setup for employees which references the external 'employees' database. I can query it with ORM from the tracker application and all is well. the unique key for employees is 'id'.
In my tracker database I have a model for 'records' table with about 12k entries. None of the field names correspond to any field names in the employees table from the employees database but some fields do contain identical information. The unique key for 'records' is Transaction_Number
Please note I did not write this application or design the databases. I am trying to "retro-fit" the tracker application to use the, now centralized, employee data .
There are 9 fields in 'records' that contain matching information in the employees database. This 9 fields contain employee id's and names but are not all the same id.
I can change the data in these 9 fields so that they are all employee id's if it would help but I need to be able to get employee data: names, addresses, etc., based on the id in any of those 9 fields
Redesigning the database would cause a rewrite of the tracker application and I really don't have the time to do all that.
To save some reading, I am not including the table structures here but I can add them if needed.
What can I do to link these two tables together?
EDIT: Added table structure for tracker.records
TRACKER.RECORDS
Transaction_Number (PK AI not null)
date
accountnumber
reasoncode
reasondesc
actioncode
actiondesc
comments
supervisor - employee->id (supervisor that created the record)
supername - employee->name
supersuper - employee->parent->name
superman - employee->parent->parent->name
eid - employee->id (employee that the record is about)
Service_Rep - employee->name
ServRepSupervisor - employee->parent->name
ServRepManager - employee->parent->parent->name
csrfollow - employee->name (who to follow up with)
Important
Read
Followup_Read
followup_Important
the employee table is using ORM_Tree to be self relational.
I need to be able to get employee info for any of those fields. I can change the data in each of those fields to be an employee id and i think i can eliminate some of them. the only ones I rally need are supervisor(employee->id), eid(employee->id) and csrfollow(can be changed to employee->id). the other fields can be discovered based on the employee->id. I still need to have those 3 fields point to the employee.id field in the employees database.
Are you aware that MySQL allows foreign keys to reference tables across databases, as long as both databases are hosted on the same instance of MySQL?
CREATE TABLE `employees` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY
-- other columns...
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `records` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`employee_id` bigint(20) unsigned DEFAULT NULL,
-- other columns...
FOREIGN KEY (`employee_id`) REFERENCES `employees`.`employees` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
You just have to qualify the referenced table name with its database name.
Re your update: You can change the name of RECORDS to RECORDS_BASE with the distinct data that belongs in TRACKER.
TRACKER.RECORDS_BASE
Transaction_Number (PK AI not null)
date
accountnumber
reasoncode
reasondesc
actioncode
actiondesc
comments
supervisor_id
eid
Important
Read
Followup_Read
followup_Important
Then create a new VIEW called RECORDS that joins RECORDS_BASE to multiple rows in EMPLOYEES:
CREATE VIEW TRACKER.RECORDS AS
SELECT rb.*,
s.id AS supervisor,
s.name AS supername,
ss.name AS supersuper,
sss.name AS superman,
emp.name AS Service_Rep,
srs.name AS ServRepSupervisor,
srm.name AS ServRepManager,
??? AS csrfollow
FROM TRACKER.RECORDS_BASE AS rb
JOIN EMPLOYEES.EMPLOYEES AS s ON rb.supervisor_id = s.id
JOIN EMPLOYEES.EMPLOYEES AS ss ON s.parent_id = ss.id
JOIN EMPLOYEES.EMPLOYEES AS sss ON ss.parent_id = sss.id
JOIN EMPLOYEES.EMPLOYEES AS emp ON rb.eid = emp.id
JOIN EMPLOYEES.EMPLOYEES AS srs ON emp.parent_id = srs.id
JOIN EMPLOYEES.EMPLOYEES AS srm ON srs.parent_id = srm.id;
I can't tell from your description what belongs in the csrfollow column. Whose name is it? Anyway I'll leave that for you to decide. I've shown how you can get a reference to each of the relevant rows in the employees table, so take your pick.