what should be database structure (fields in a table) for a user account. what I want when an admin create a new user account, the account should be in Inactive state until the user set the password.
When the admin create the user account it create a url and send to that user on his registered email-Id when he open that url the user see a page for setting password. when he set the password the user account should be activated.
my sample Database structure is below
CREATE TABLE user_account (
user_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
fst_name VARCHAR(50) NOT NULL,
lst_name VARCHAR(50) NOT NULL,
email_id VARCHAR(50) NOT NULL,
login_password VARCHAR(64) NULL DEFAULT NULL,
user_created_date DATETIME NOT NULL,
PRIMARY KEY (`user_id`),
UNIQUE INDEX `email_id` (`email_id`)
)
I want to know should I add more field's in the table or a new table for accomplishing this task.
The database structure is a result of what you require your user-related processes should be like. You can derive from the requirements you enumerated what fields you would need. This is, however, not a technical but a model-related question. The answers to this are more or less straight-forward.
If you need the time of registration, create a date field
If you need the user's IP on registration, create a varchar field
If you need to know which user has created this account (e.g. an Admin), create a field that references another User
If you need the user to have different states (DEACTIVATED, DELETED etc.), create a varchar or and int field and define in your application what values it may have.
Related
I've encountered an issue while assisting someone with their legacy web application that's being hosted on Apache Tomcat with a SQL DB. Most of the user accounts on the DB that has access to the web application has been locked out due to max login attempts. To make things worse, they do not remember the passwords; including the admin accounts access that is able to make resets via the web app. I'm trying to either A) Create a new admin account in the table to get admin access back to the webapp for them or B) Recover their passwords and reduce the login attempt limits that have cause majority of them to be locked out. Really stuck from here and not sure where to progress.
This is what I've done:
I've looked up the SQL User Tables to ascertain if I can see their passwords in plain text. However, the password columns are ciphered in someway. From the only user that has access to the web app. We confirmed that passwords are alphanumerical - but on the tables the register as numericals like:
-1662545724
I had also checked if the table creation has some sort of hashing or salt did not show anything. This was the output:
CREATE TABLE user (
userID int(10) unsigned NOT NULL auto_increment,
userName varchar(100) NOT NULL,
password varchar(100) NOT NULL,
name varchar(255) NOT NULL,
initials varchar(20) NOT NULL,
tries int(10) unsigned NOT NULL,
firstLogin tinyint(1) NOT NULL,
roleID int(10) unsigned NOT NULL,
createdBy varchar(100) NOT NULL,
createdDate date NOT NULL,
createdTime time NOT NULL,
modifiedBy varchar(100) NOT NULL,
modifiedDate date NOT NULL,
modifiedTime time NOT NULL,
PRIMARY KEY (userID),
KEY FK_user_roleID (roleID),
CONSTRAINT FK_user_roleID FOREIGN KEY (roleID) REFERENCES role (roleID)
) ENGINE=InnoDB AUTO_INCREMENT=142 DEFAULT CHARSET=latin1;
The user table insert is as shown below. Only 1 singular account is currently active amongst about a 100. We have a plaintext password for it and this password is reflected as its ciphered text in point 1 - Will it be possible to simply duplicate the line, change the username and elevate the roleID to get a new admin user to the web app?
(userID,userName,password,name,initials,tries,firstLogin,roleID,createdBy,createdDate,createdTime,modifiedBy,modifiedDate,modifiedTime)
Will only get access to the server again tomorrow. In the mean time i do have a complete backup of the SQL file only. Seek your kind advices on how i can solve this issue.
I am new to MySQL, so I'll explain by example.
I have 2 tables:
Admins(
id int auto_increment not null,
primary key(id)
);
Users(
admin_id int not null,
id varchar(255) not null,
password varchar(255) not null
);
I basically create an entry for a admin, then I want the admin to be able to add users that are tied to his ID, so then I can also read all users tied to that certain admin (the id and password parameters, to be exact)
I cannot figure out the syntax for how to do this, could anyone provide some help? Maybe there is a way to just write all that data straight in the admin table somehow so I don't have to use 2 tables?
I use PHP to do everything, by the way
I would like to save user data in my database.
There is common data about the user account (nickname, password, etc.) but also data like firstname, name, age, location, ...
How can I manage my data base? Should I create different tables? One containing common user data and another containing all the other data?
This is a design choice, and it basically depends on how much information you usually need, and how many extra fields you have.
Option 1: Keep them in the same table, if its not too much or you usually need all the data.
Option 2: Create a User Profile table, that contains the user data that its related to the person and not the account.
create one single table.
CREATE TABLE `admin`
(
`User_Name` varchar(60) NOT NULL,
`Password` varchar(60) NOT NULL,
'firstname' varchar(60) not null,
'Age' int(11) Not null,
'Location' varchar(50) NOT NULL,
PRIMARY KEY (`User_Name`)
)
ENGINE=InnoDB DEFAULT CHARSET=latin1;
Create 2 tables:
1. userProfile
create table userProfile(
UserID int primary key auto_increment(1,1),
firstname varchar(50),
age int(11),
location varchar(50));
2.userAccounts:
create table userAccounts(
ID int primary key auto_increment(1,1),
UserID int(11),
UserName varchar(50),
Password varchar(50));
there is a relation between Table1(UserID) and Table2(UserID).
I currently have a database which many users can access and make changes to. The is also a log database that stores all changes to tables within the database using triggers.
I would like to add the ability to approve edits before they are changed in the database.
What would be the best way to go about this?
We have something similar on one of our sites, we've added a bunch of tables:
users sites ... etc
Then we have a bunch of shadow tables:
users-shadow sites-shadow ... etc
The shadow tables have identical structures to the real tables except for an added line for the user who made the change. So first we use this query when a change is submitted by a user who needs to have his/her database actions approved:
REPLACE INTO users-shadow (user_mod,id,username,password,salt...) VALUES (16,50,'bob','stuff','salt'...);
Obviously, make sure this isn't open to injection, use prepared statements etc.
When approved, a row in the shadow table is simply removed from the shadow table, the user_mod value dropped and changes (non-null values) inserted into the real table (or updated if an id is specified, using REPLACE syntax). We do this logic in perl so sadly don't have any SQL on hand for it.
Remember that SQL REPLACE does a DELETE and an INSERT rather than an UPDATE. You will need to amend any triggers to allow for this behaviour.
Note: The reason we didn't use an 'approve' flag was that we needed the ability to amend existing records, of course we couldn't have multiple records with the same primary key.
well i have made this system once and here is my solution for DB structure and over all algorithm:
there should be a sub system of admin panel which different users can manage their products but every change should be approved by administrator before going affecting the main Product table. there is three main table:
1.Product : store products that have final approved and are used in entire system
2.Changes_versions : a table with One To Many Relation with Product Table that indicates each change version is committed by who , when ,and is approved/rejected by admin or still is in Pending state .table structure is as following :
CREATE TABLE changes_versions(
xid int(11) unsigned NOT NULL AUTO_INCREMENT,
xcreated_date datetime DEFAULT NULL,
xupdated_date timestamp NULL DEFAULT NULL,
xversion int(11) DEFAULT NULL,
xobject_id int(11) DEFAULT NULL,
xobject_type varchar(255) DEFAULT NULL,
xstate enum('PENDING','ACCEPTED','REJECTED') DEFAULT 'PENDING',
PRIMARY KEY (xid)
) ENGINE=InnoDB AUTO_INCREMENT=165 DEFAULT CHARSET=utf8
3.Changes : a table that have One To Many relation with Changes_versions table that keep every column change record of the main Table (here i mean product table) and by approving a change_version record by admin its related changes records will be placed in main table column. table structure is as following :
CREATE TABLE changes(
xid int(11) unsigned NOT NULL AUTO_INCREMENT,
xcreated_date datetime DEFAULT NULL,
xcreated_by varchar(255) DEFAULT NULL,
xupdated_date timestamp NULL DEFAULT NULL,
xupdated_by varchar(255) DEFAULT NULL,
xversion_id int(11) DEFAULT NULL,
xcolumn_name varchar(255) DEFAULT NULL,
xcolumn_value varchar(255) DEFAULT NULL,
xstate enum('PENDING','ACCEPTED','REJECTED') DEFAULT 'PENDING',
xadmin_review text,
PRIMARY KEY (xid)
) ENGINE=InnoDB AUTO_INCREMENT=764 DEFAULT CHARSET=utf8
with this system and table schema i handled to work with record changes, user fetch list of records ,if user have any Pending state change_version, system will pull its related changes records and place them in the right column in the fetched product row(temporary just for displaying) , so even if user has any pending state changes he/she can see its changes in his/her panel(not main system, only his/her panel).
at the end if system administrator accept a user changes_version version and its related changes records ,system should place each changes table record in the right column of product table(for example i used product table, with this system you can versioning and admin approving any table).and change version record state to approved and its changes related records to approved to. so with this structure you can save and versioning different tables and keep log of each version changes.
Here are two tables I designed for managing user accounts.
create table if not exists users (
id int unsigned not null auto_increment,
username varchar(100) not null,
password binary(60) not null,
first_name varchar(100) not null,
last_name varchar(100) not null,
role_id int unsigned not null,
primary key(id),
unique(username)
);
create table if not exists roles (
id int unsigned not null auto_increment,
role varchar(100) not null,
primary key(id),
unique(role)
);
I think I need to normalize the first table, e.g. splitting the first table into some sort of user_info(first_name, last_name, ...) and account (username, password, role_id). The problem I have is that I am very uncertain of why I need to do this, as I can't really explain why it isn't in 3NF.
EDIT
A user can only have exactly one role (admin, poweruser, user).
You only need to separate the user information and account information if a user can have multiple accounts or an account can have multiple users. If the user-to-account relationship is always 1-to-1, then you're normalized as is.
Occasionally it makes sense to separate out columns in a 1-to-1 relationship if the columns in the second table will be used rarely. However, in this case, it seems as though both tables would always be populated, so there's nothing to be gained by separating those columns.
Decompose the users table further only if it's allowable to have a user id and username without a corresponding first name and last name. Otherwise it looks like your tables are already in 5NF.
I'm not a SQL Expert, but this tables looks very normalized to me. You should normalize a table to save space:
If you have a column, like role and you have 20 users with 5 roles, each roles uses 10byte, you will have 20 * 10bytes = 200bytes.
But if you normalize the table, as you have done it already, you will only need 5 * 10bytes = 50bytes for the role name, 5 * 1byte = 5byte for the id in the role table and 20 * 1byte = 20byte for the id in the user table.
200bytes not normalized
50bytes + 20bytes + 5bytes = 75bytes in normalized form.
This is only a very incomplete and basic calculation to show the background.