I have 2 tables (with identical structure) and I want both to update after a form submission and both have the exact same data.
The tables structure are as below:
id | parent_id | name | surname
The id is the primary key, which means that I cannot execute the following query because it throws an error (Duplicate entry '1' for key 'PRIMARY'):
INSERT INTO table_2 SELECT * FROM table_1
My goal is to keep the data identical (including the PRIMARY) in both tables after a row is updated or a new row is added. How can I do this and avoid the Duplicate entry error?
Because your forms are on two different pages, you need some way to connect the two when creating the second record.
Using language as an example, I would have my "primary" language form on one page. Submit that information to your "default/primary" language table.
Then, on your "secondary" table, I would include a select input that listed out my "primary" languages. The values would be the primary key of your "primary" language. The user has to choose a parent language to connect to. Otherwise the secondary language has no idea who it belongs to.
On your secondary table, I would not have an auto_incrementing primary key. That way you can share the same ID as your parent table.
I would create a foreign key to the "secondary" table that was related to the "primary" table id field.
This will allow you to run queries like:
Not tested at all - and probably incorrect syntax.
SELECT * FROM `primary` WHERE something JOIN `secondary` ON `secondary.id` WHERE `secondary.id` = `primary_id`
But, that would give you an idea of what I'm talking about.
Edit
Based on our conversation, it sounds like you will either need to drop your secondary table on each insert (to clear the primary keys). Or I found this thread on resetting the key that might be helpful.
Related
I'm not sure if a "sub-table" is the proper term for it, so let me explain a bit better.
I'm setting up a website which contains multiple items, now I've created 2 separate tables in my MySQL database: general and platforms.
My goal now is to split the data of each item into these 2 tables, which works fine so far, but my problem now is the following:
The platforms table has the following structure:
ID
Name
URL
I want to keep track of each item by their ID, so the ID for item #1 should be equal in all tables.
Now, if I have say 3 different platforms for item #1, I'll add every element in the platforms table, but their ID's don't match.
And if I have multiple items, each with multiple platforms it will start to look really messy.
Is it possible to have a table that looks like this?
ID
Name
URL
Hopefully the images clarify it more, basically; I want to have a table that groups together multiple elements.
Is this possible or would I have to do it by assigning a secondary non auto-incrementing ID to each item and manually group the platforms together in PHP?
Looks like you have a one-to-many relationship. Generically, that means
a row in general can be related to zero, one or more rows in platforms.
a row in platforms is related to exactly one row in general.
To implement this design, store the id value from the general table as a foreign key in the platforms table.
id
general_id -- foreign key references id in general table
name
url
Rows in the two tables are related by virtue of a common value.
id general_id name url
--- ---------- --------- --------------------------
77 1 Platform1 http://item1.com/platform1
78 1 Platform2 http://item1.com/platform2
79 1 Platform3 http://item1.com/platform3
To have the database enforce referential integrity, you would need to use a storage engine that supports that (e.g. InnoDB), and you can declare a constraint
ALTER TABLE `platforms` ADD
`general_id` INT NOT NULL COMMENT 'fk ref general.id' AFTER `id`;
(The datatype of the general_id columns must exactly match the datatype of the id column in the general table.)
Before you can enforce the constraint, the values in the new general_id column will have to match a value in the referenced column.
To define the constraint:
ALTER TABLE `platforms`
ADD CONSTRAINT FK_platforms_general
FOREIGN KEY (`general_id`) REFERENCES `general`(`id`)
I've just started exploring SQL databases, but I've run into an issue with how I store 'compound' structures in an existing table (if that's even the right way to go about it). For example, let's say that I have a database table with rows of users, where each user has a Unique ID, a hashed password, an email address, a phone number, etc.
Simple enough. But, then I want to allow each user to create and store an array of posts. Each post would have a post id, content, date, and various other metadata. If this was C++, I would probably have an array/vector of Posts as a member of the User class, and than I'd store an array/vector of User objects somewhere. Is it possible to store a table within a table in SQL, so that each user has access to their own individual table of posts?
Or, would it be better to create two separate tables (a users table, and a posts table), using some common element (like user ID or user name) to retrieve user-specific data from the posts table, and vice-versa?
I'm trying to understand how to implement a complex database that might be able to manage a large number of users, with user-specific sets of data like posts, messages, etc. So what might be a good approach to take going forward?
As you already mentioned, in relational data model, you can define two tables like below:
table 1 : Users
user_id user_name
----------- ------------------
1 'Tom'
2 'John'
table 2 : Posts
post_id user_id content post_date
-------- ---------- ------------------- ---------------------
1 1 'Hello, I am Tom.' 2014-04-02 14:14
2 1 'good bye' 2014-04-02 20:10
3 2 'I am John' 2014-04-02 22:22
You can read an introductory article here:
Relational_model:
http://en.wikipedia.org/wiki/Relational_model
Hope this helps.
You don't store table within table. You can store data in multiple tables and assign primary key for one table and foreign key for another table.
Read about Primary key, Foreign key and Relational Model.
Once your these concepts are cleared read about Database Normalization
You don't store tables within tables. As your third paragraph suggests, the strategy is to use some common key to "relate" table rows to each other.
The "unique ID" you describe is usually called a "primary key". You might have a table of users with a primary key that auto-increments each time you add a record. A function would be available to you so that after inserting, you could determine what the primary key is of the record you just added, so that you can add records to other tables that refer to the primary key of the users table.
You should probably read about Database normalization ant the relational model, specifically about the differences between Normal Forms.
With regard to selection of a field to relate posts to users, I suggest you don't use the username, and instead use some internal reference that isn't visible to the users. While your application might not allow it now, if you wanted to offer users the opportunity to change their username, tying internal database structure to something based on user input would only cause problems in the future.
I would like write a php script that merges several databases, and I would like to be sure of how to go around it before I start anything.
I have 4 databases which have the same structure and almost same data. I want to merge them without any duplicate entry while preserving (or re-linking) the foreign keys.
For example there is a db1.product table which is almost the same as db2.products so I think I would have to use LIKE comparison on name and description columns to be sure that I only insert new rows. But then, when merging the orders table I have to make sure that the productID still indicates the right product.
So I thought of 2 solutions :
Either I use for each table insert into db1.x as select * from db2.x and then make new links and check for duplicate using triggers.
Either I delete duplicate entries and update new foreign keys (after having dropped constraints) and then insert row into the main database.
Just heard of MySQL Data Compare and Toad for mySQL, could they help me to merge tables ?
Could someone indicate to me what should be the right solution ?
sorry for my english and thank you !
First thing is how are you determining whether products are the same? You mentioned LIKE comparison on name and description. You need to establish a rule what says that product is one and the same in your db1, db2 and so on.
However, let's assume that product's name and description are the attributes that define it.
ALTER TABLE products ADD UNIQUE('name', 'description');
Run this on all of your databases.
After you've done that, select one of the databases you wish to import into and run the following query:
INSERT IGNORE INTO db1.products SELECT * FROM db2.products;
Repeat for the remaining databases.
Naturally, this all fails if you can't determine how you're going to compare the products.
Note: never use reserved words for your column names such as word "name".
Firstly, good luck with this - sounds like a tricky job.
Secondly, I wouldn't do this with PHP - I'd write SQL to do the work, assuming this is a one-off migration task and not a recurring task.
As an approach, I would do the following.
Create a database with the schema you want - it sounds like each of your 4 databases have small variations in the schema. Just create the schema for now, don't worry about the data.
Create a "working" database, with the same schema, but with columns for "old" primary keys. For instance:
table ORDER
order_id int primary key auto increment
old_order_id int not null
...other columns...
table ORDER_LINE
order_line_id int primary key auto increment
old_order_line_id int not null
order_id int foreign key
...other columns...
Table by table, Insert into your working database from your first source database. Let the primary keys auto_increment, but put the original primary key into the "old_" column.
For instance:
insert into workingdb.orders
select null, order_id, ....other columns...
from db1.orders
Where you have a foreign key, populate it by finding the record in the old_ column.
For instance:
insert into workingdb.order_line
select null, ol.order_line_id, o.order_id
from db1.order_line ol,
workingdb.order
where ol.order_id = o.old_order_id
Rinse and repeat for the other databases.
Finally, copy the data from your working database into the "proper" database. This is optional - it may help to retain the old IDs for lookups etc.
I have created a PHP script and I am lacking to extract the primary key, I have given flow below, please help me in how can i modify to get primary key
I am using MySQL DB, working for Joomla, My requirement is tracking the activity like insert/update/delete on any table and store it in another audit table using triggers, i.e. I am doing Auditing. DB's table structure: Few tables dont have any PK nor auto increment key
Flow of my script is :
I fetch out all table from DB.
I check whether the table have any trigger or not.
If yes then it moves to check for next table and so on.
If it does'nt find any trigger then it creates the triggers for the table, such that,
it first checks if the table has any primary key or not(for inserting in Tracking audit table for every change made)
if it has the primary key then it uses it further in creation of trigger.
if it doesnt find any PK then it proceeds further in creating the trigger without inserting any id in audit table
Now here, My problem is I need the PK every time so that I can record the id of any particular table in which the insert/update/delete is performed, so that further i can use this audit track table to replicate in production DB..
Now as I haave mentioned earlier that I am not available with PK/auto-incremented in some table, then what should I do get the particular id in which change is done?
please guide me...GEEKS!!!
If I understand your question right, you need a unique identifier for table rows that have no primary key and no other kind of unique identifier. That's not easy to do as far as I can see. Other databases have unique Row IDs, but mySQL does not. You could use the value of every column to try and identify the row, but that is far from duplicate-safe - there could be two or more rows containing the exact same values. So I'd say, without a unique identifier, this is something that simply cannot be done.
Some ideas in this SO question:
MySQL: is there something like an internal record identifier for every record in a MySQL table?
Im building a site where a user can add people to their "list". This list belongs to the user, but im wondering whats the best way to store/retrieve/loop through this list in a function, to show the people who are on the list, that they are there and who created it.
So once the list of usernames is created, i would assume store it in a mysql table field, then write a function that would search that table to find any lists that affect the currently logged in user.
My question is two fold. First, assuming the list is just a-z 0-9 and hyphens and underscores (no spaces in the usernames, but separated with spaces), what would be the best field type to store this as in mysql. Secondly, what would be the best/fastest method for searching for a username across many lists?
Varchar, indexing and additionally caching.
You're creating a usertable with a username and userid field. Then create a table user_relation where you combine userid's so you have matches. Place indexes on all foreign key relations. That should give a pretty decent performanceboost :)
edit some additional info for setting it up
Table: User
UserID - Int (8) - Primary Key, Auto increment
Name - Varcahr (30)
EmailAddress - Varchar (90) - Unique
Table: UserRelation
ID - Int (8) - Primary Key, Auto increment
UserID_Source - Int (8), Index (this is the user)
UserID_Friend - Int (8), Index (this is a friend / relation from the user)
This way you can easily store relations to a certain user.
To get some results use a query like:
SELECT `User`.*, `User`.`UserID` AS `UserID_Source`
FROM `User`
WHERE `User`.`UserID` = `user_relation`.`user_id_source`
You can extend the query by a JOIN to direct fetch the relation matches or use another query for that ;)
You best option would be to store each name in its own row.
If your list contains references to other members (each person has their own list) your best bet is to create the data in an MySQL table of some kind (as MySQL is optimized for this kind of thing), for example you would need 2 simple tables, table one (user table) would have 2 columns. ID (INT or BIGINT), UserName (VARCHAR).
Then your second table (user links) would have 2 entries depending on if linking is done bidirectionally or unidirectionally see bellow.
Bidirectionally: The table would have 2 columns, User1(INT or BIGINT), User2(INT or BIGINT). To retrieve a list, simply query this table for all entries where the user id is in either User1 or User2.
Unidirectionally: The table would have 2 columns, Owner(INT or BIGINT), Person(INT or BIGINT). To retrieve a list for a user simply query this for all entries that are owned by such user.
The difference between the two is, with bidirectionally if i add you to my list, i am automatically on your list. With Unidirectionally that is removed, so you have to add me to your list for me to appear on your list, even if your on my list.