There is a checking process during signing up so that an existing username and e-mail can’t be used with a new registration. After validation, the data is stored immediately and we can’t see what causes the problem. Maybe we should use some type of locking?
We use a unique hash in the form, which we swap after every process, somehow it still occurs that a user registration is stored twice because of double clicking or other event.
Do you have any ideas how we could prevent double entries?
Thank you.
If you want values to be unique in a table, then use a unique constraint in the table:
alter table t
add constraint unq_username_email unique (username, email);
Let the database do the work, so it guarantees data integrity. Then you don't have to worry about race conditions.
I should note: You might want two unique constraints. It is unclear exactly what you want to be unique:
alter table t add constraint unq_username unique (username);
alter table t add constraint unq_email unique (email);
Related
I need to create the database schema and include it in my software requirements specification for my school project, however, when I try to create a relationship between 2 tables, I get Error: Missing index on column(s).
I think #HazarathChillara has this right; you need to create primary, unique, or index keys.
You said every table has an primary key, but did you make each foreign and referenced key an index as well? It sounds like you neglected to properly set up your table structure; I only get the error when I don't have a primary key or index on the particular columns I'm working with.
"MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan"
You can just put an INDEX on the foreign key (often my referenced key is a primary key anyway, so I don't need any additional key on that column).
This error appears only when you neglect table structure. Make sure that you Indexed a foreign key as well. you can see i marked how could i select my foreign key as index.In this Image I am indexing selected, 'sr' my foreign key
As Usman Khan said you have to go to the structure tab of the particular table and clicked on more options and select 'INDEX' for the foreign key.
the below image will help you how to do it
I think i have another simple solve,
thing is, phpMyAdmin wont allow the addition of foreign keys to an already available data entry, so here is the my simple solve,
1. ensure to backup your database
2. confirm that your data was backed-up securely, recommended Offline backups
4. delete all data entries in all tables that will be part of the new relationship.
5. now Create the relevant relationships.
6. be sure you have created all required and preferred relations to avoid the need to
export data again
I have a SQL table called "user" and a table "login" that has a foreign key constraint to a user. I want to be able to delete a row in the user table, even if there are login rows that reference it. Right now the database stops me from doing this.
Does anyone know how I can alter the table (through SQL or preferably through PHPmyAdmin to allow me to do this?
The tables were created automatically through Django.
Edit: To clarify: I don't want to cascade the delete. That is, I want the rows in the Login table to remain even though the user they reference is gone.
If you want this kind of behavior you have to create the foreign key with an ON DELETE CASCADE clause. With an ON DELETE CASCADE foreign key all rows referencing the user will be deleted with the user.
See: http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
Edit: If you want to keep the user_id in your login tables you just have to drop the foreign key. Anyway, If you are asking this is because you should probably do a logical delete instead of a physical delete: Physical vs. logical / soft delete of database record?
Proper way to do this is to mark offending users as "inactive" so they can't login and you still maintain referential integrity of your database.
Deleting data from master table that has referential integrity links to some data in slave table is bad praxis.
I'm in the process of redesigning some application security log tables (things like when users log in, access different files, etc.) to address some changing requirements. They were originally made with MyISAM, but don't really get accessed that often and switching to InnoDB and adding a bunch of foreign keys for data integrity would really be more beneficial. Since I have to remake the tables anyway, I figure this is as good a time as ever to make the switch.
For the most part, everything is straightforward foreign keys and works as expected. The only part that where I'm trying something weird and hitting problems is with user_ids. Each record in these log tables is associated with a user_id, and I want to make sure the given user_id exists when a record is inserted. Adding a foreign key that references the user table solves that problem - simple stuff. Here are some concise, representative tables:
The User Table
CREATE TABLE tbl_user (
id INT(10) NOT NULL AUTO_INCREMENT,
first_name VARCHAR(50),
PRIMARY KEY(id)
) ENGINE=InnoDB;
Example Log Table
CREATE TABLE tbl_login_time (
id INT(10) NOT NULL AUTO_INCREMENT,
user_id INT(10) NOT NULL,
login_at TIMESTAMP NOT NULL,
PRIMARY KEY(id),
CONSTRAINT 'tbl_login_time_fk_1` FOREIGN KEY (user_id) REFERENCES tbl_user
ON UPDATE CASCADE ON DELETE ???
) ENGINE=InnoDB;
My problem is that I want the foreign key enforced for inserts, updates to be cascaded, but deleting records in tbl_user to not affect tbl_login_time at all. Normally users get marked as inactive, but every once in awhile a user gets deleted entirely yet the logs need to be maintained.
The MySQL docs lists 6 options for ON DELETE, and none of them sound appropriate:
RESTRICT: Would prevent the deletion in tbl_user.
NO ACTION: Gets evaluated just like RESTRICT.
CASCADE: Would delete in tbl_user like I want, but also in tbl_login_time.
SET NULL: Would delete in tbl_user, and leave the row in tbl_login_time but nulls out the data. Close but no cigar.
SET DEFAULT: MySQL recognizes it, but rejects it.
Omit ON DELETE: Equivalent to RESTRICT.
I've never used a foreign key like this before (enforce INSERT and UPDATE but not DELETE), and after reading a lot of other questions it doesn't seem like anyone else does either. That should probably tell me this is the wrong approach, but can it work somehow?
My problem is that I want the foreign key enforced for inserts,
updates to be cascaded, but deleting records in tbl_user to not affect
tbl_login_time at all.
You can't accomplish that with a foreign key constraint.
In some applications, ON DELETE SET NULL makes sense. But your application is essentially a log file stored in a SQL database. You have a significant problem in that you want to delete identifying information (users), but retain their ID numbers in some cases. I frankly don't understand why you're willing to retain the fact that user 23332 logged in at 18:40 today, while not caring whether you can identify who user 23332 is.
You have a few options.
Drop the logfile table, and store logfile data in a file in the filesystem, not in the database. If I were in your shoes, I'd consider this first. If we're talking about a database that's somehow accessible over the web, make sure the log file is stored outside the web root. (I'd store it under /var/log with all the other log files.)
Use foreign key constraints, and never delete a user.
Use foreign key constraints, and live with the effect of ON DELETE SET NULL or ON DELETE SET DEFAULT. In this particular application ON DELETE SET NULL and ON DELETE SET DEFAULT are semantically equivalent. Both replace good data with data that doesn't identify the user. If you can't identify user 23332 anyway, who cares whether you know she logged in at 18:40 today?
Drop the foreign key constraints, and use triggers to do whatever you like.
I'm pretty sure we agree that the most obvious option--use foreign keys with ON DELETE CASCADE--is simply wrong for your application.
Given the schema:
What I need is having every user_identities.belongs_to reference an users.id.
At the same time, every users has a primary_identity as shown in the picture.
However when I try to add this reference with ON DELETE NO ACTION ON UPDATE NO ACTION, MySQL says
#1452 - Cannot add or update a child row: a foreign key constraint fails (yap.#sql-a3b_1bf, CONSTRAINT #sql-a3b_1bf_ibfk_1 FOREIGN KEY (belongs_to) REFERENCES users (id) ON DELETE NO ACTION ON UPDATE NO ACTION)
I suspect this is due to the circular dependency, but how could I solve it (and maintain referential integrity)?
The only way to solve this (at least with the limited capabilities of MySQL) to allow NULL values in both FK columns. Creating a new user with a primary identity would then look something like this:
insert into users (id, primary_identity)
values (1, null);
insert into identities (id, name, belongs_to)
values (1, 'foobar', 1);
update users
set primary_identity = 1
where id = 1;
commit;
The only drawback of this solution is that you cannot force that a user has a primary identity (because the column needs to be nullable).
Another option would be to change to a DBMS that supports deferred constraints, then you can just insert the two rows and the constraint will only be checked at commit time. Or use a DBMS where you can have a partial index, then you could use the solution with an is_primary column
I would not implement it this way.
Remove the field primary_identity from table users, and the add an additional field to table user_profiles called is_primary, and use this rather as the indicator of a primary profile
This will prevent having NULLs for FKs, but still does not enforce for primary profile to exists -- that has to be managed by application.
Note the alternate key (unique index) {UserID, ProfileID} on Profile table and matching FK on PrimaryProfile.
The problem seems to be that you are trying to keep the primary identity information in the user_identities table.
Instead, I suggest you put the primary user info (name/email) into the users table. Do not foreign key to the user_identities table.
Only foreign key from the user_identities table
All constraints will now work ok as they are only one way.
user_identities cannot be entered unless the primary user (in table users) is present. Similarly the primary user should not be deletable where there are existing child identities (in user_identities).
You might want to change the name of the tables to "primary_users" and "secondary_users" to make it obvious what is going on.
Does that sound okay?
This question was raised at How to drop tables with cyclic foreign keys in MySQL from the delete side of things, but I think that one of the answers is applicable here as well:
SET foreign_key_checks = 0;
INSERT <user>
INSERT <user identity>
SET foreign_key_checks = 1;
Make that a transaction and commit it all at once. I haven't tried it, but it works for deletes, so I don't know why it wouldn't work for inserts.
I've not used it, but you could try INSERT IGNORE. I'd do the two of those, one for each table, such that once they are both done, referential integrity is maintaing. If you do them in a transaction, you can roll back if there is a problem inserting the second one.
Since you're ignoring constraints with this feature, you should do that check in program code instead, otherwise you may end up with data in your database that ignores your constraints.
Thanks to #Mihai for pointing out the problem with the above. Another approach would be to disable constraints whilst you do inserts, and re-enable them afterwards. However, on a large table that might produce more overhead than is acceptable - try it?
The relation of PRIMARY is equal to fk_student_single_user1. So i must remove one of them.
The problem is, i can't remove or rename PRIMARY in workbench, the program does not allow, and if i delete fk_student_single_user1, i also delete the foreign key. The only way is delete PRIMARY in the phpmyadmin.
But i think that exists any problem in my eer model, it is supposed an export without bugs.
I deleted my previous column id, because two foreign keys can be the primary key of the table.
How i can solve that?
Try deleting the foreign key, dropping the needless fkey index, and re-adding the foreign key using plain sql (alter table...) rather than your GUI.
The SQL spec requires a unique index on the target column, so there's no reason to add an extra (non-unique) index on top.
If MySQL still adds the index, you might want to report it as a bug (as well as to http://sql-info.de/mysql/gotchas.html).
If not, you might want to investigate whether the index was added by your GUI in the first place. And if so, report the issue as a bug to the GUI's creator.