I want to know what is best table structure and indexes for users table (login by email and password) for best performance.
I don't want to use usernames.
I want to login with unique index (for better performance) with user email.
Maybe best performance will be unique index for email and password together.
Problem is that I want to be email indexed as unique for faster login.
But in this case bad user can prevent another user to register knowing his email.
The only idea I could think of some sort of unique email and password hash in one unique column. But I want know how its done the best.
Part of my user table index structure (DB is MySQL)
user_id - PRIMARY
email - UNIQUE
password
verified (after verify email)
Simple solution:
Send verification email with link to cancel registration (I didnt register)
Related
I want to create a user into User table.
These are my process.
continue when email and nickname are not exist
creates a user
I think if I didn't lock the User table while creating a user then email and nickname can be duplicated.
Any ideas?
Avoid locks where possible. Instead, use a unique index, and simply insert the user. If the user or email exists, your query will return an error similar to:
Error Code: 1062. Duplicate entry 'john.doe#example.org' for key 'unique_email'
This should be done with 2 separate indexes. One for email, and one for users. This has the following advantages, and almost zero disadvantages:
It enforces database consistency. At no point will 2 users have the same email address, nor the same username.
It avoids unnecessary locks.
It avoids technical debt. Let's say down the line you add a user importer. In the importer you fail to check for duplicate accounts, or add in locks, or forget to check if the username or email exists. Your importer will work, and your database will now contain entries that duplicate each other.
I'd try to create a combined unique key on email and nickname
CREATE UNIQUE INDEX some_index_name ON user_table(email , nickname)
Edit: To address the comments below, we should as well create 2 more unique indexes for email and username, to make sure 2 users with separate emails can share the same username and vice versa.
I am creating a simple web application.
Is it wrong to identify user by it's user name even in the application low level?
For example, say I have a authentication token table that has three columns: token, userID, expDate.
Will it be wrong to put the user username in userID column?
Do I have to worry about the fact that everybody knows the user ID in my DB?
No, I don't think there's anything wrong with that particularly. I've seen that in practice at very big sites - just make sure that you have a unique constraint and index for that value (better, make it the primary key). Also, consider that using the username as their ID means you can't let the user change their username later without breaking existing links (say, if your user shares their user page externally).
I'm not sure, but there might be some overhead from using a string instead of a number.
Also it could be a hassle to update other database tables if a user's username ever changes.
Or should I have username, email, password and set save username also as email?
edit: I am not using email as the pk but am using a unique index on the email
I feel like if I decided to change to openid/usernames I can still do that in the future by adding another column
I'd do email/password. And if you ever want to add usernames you can upgrade it then. No need to use extra fields if they're the same and you don't need them.
Might as well just have the email column since it functions as both, no point in repeating data in your table. Just remember DO NOT SAVE PASSWORDS AS CLEARTEXT :) Also you should have a Primary Key id column
I am using ActsAsParanoid for soft deleting users.After deleting(soft) a user, my client wants to create user with same email id.But it generating unique field error since email column is unique.So my question is can we set the uniqueness for email column only if the deleted_at column is null.
Pls reply if u dont understand my question.
I suppose you could change the uniqueness constraint of your users table to be:
UNIQUE (email, deletion_date)
This would effectively:
For standard (non-deleted) users, guarantee they have unique email addresses, since their deletion dates would presumably all be NULL.
For deleted users, not make any guarantee about email addresses, since they all have unique deletion dates.
For new users, allow them to use an email address that a deleted user has, since the new user will have a NULL deletion date, while the deleted user has a value there.
Ah, just change old email to something like
Me#yourmail.com_deleted
That way if you need to view the old email it's everything before the underscore deleted.
In other words here have new user create new account.
Probably have a mutator in the background add the underscore deleted on the old account.
Underscore deleted just an example.
Looking to create a database table that saves user information (primarily user and password).
Is the best way to hash (password) and user?
Should I encrypt the name of user too?
If i have a table of passwords and another with users data, how i can associate/link them?
The login is not the problem, the question is how to associate the tables (table of passwords and table of data for each user)
Thanks
You basic User table would look something like this:
User Table
-------
id username password
1 mike ##$90sDfsa
Where the password is a hashed version (with a salt) of my password.
You should of course hash the password before storing it. Ideally with an unique salt.
As a hash function you should not use something like SHA-*, because the cryptographic hash functions are designed to be fast. This makes it easy for someone getting the hash to try a large number of possible passwords very fast.
Use a password hash function like bcrypt which is designed to be arbitrarily slow.
The login is not the problem, the
question is associate the tables
(table of passwords and table of data
for each user)
To associate the tables you can work with relations:
http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html#04
How to create relationships in MySQL
I would store the hashed and salted password in the table with the rest of the users data. If you really want to store the passwords in a seperate table store the user id with it to associate passwords with users. In general use a strong hashing algorithim e.g. SHA251 and salt the passwords to prevent rainbow table attacks. I don't think that you should need to hash the username.
As I commented above, I would just hash the password.
Also, why are you storing users and passwords in a separate table? They are related, and should be in the same table. Data such as addresses would belong in a separate table.
You can use surrogate keys to do the relation between the tables, if you absolutely must have two tables, one with hashed/salted passwords, the other with user information.
You could have a setup like this:
CREATE TABLE users (USER_ID INTEGER,
PASSWORD_ID INTEGER,
USER_ATTRIBUTE VARCHAR(30));
CREATE TABLE passwords (PASSWORD_ID INTEGER,
PASSWORD_HASH VARCHAR(255));
PASSWORD_ID is the surrogate key, you use it in the users table to reference the value in the passwords table. You can join the tables together with a SQL query:
SELECT *
FROM users INNER JOIN passwords
ON users.PASSWORD_ID = passwords.PASSWORD_ID;