MySQL fetch and insert where value is - mysql

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

Related

Can I have a string of TIMESTAMPS in MySQL?

I am just wondering to know can I have a string of TIMESTAMPs in a MySQL table schema like following:
CREATE TABLE IF NOT EXISTS auth (
id BINARY(16) PRIMARY KEY,
email VARCHAR(64) UNIQUE NOT NULL,
password VARCHAR(64) NOT NULL,
admin INT NOT NULL DEFAULT 0,
created_at [TIMESTAMP]
);
Unfortunately the above code gives me a syntax error!
My idea is to have a list of TIMESTAMs to store every future updates inside of it, something like ['2023-01-01' , '2023-02-02' , ....]
If this is not possible in my suggested way, how can I store any changes of one column of a table like created_at column? Should I do it in the web-server?

Database structure for new user account

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.

How to create a MySQL database for users data

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).

Inserting a value into one table based on insert from another table

I have this table for users that stores their usernames and other data, thats done like this (stripped down):
CREATE TABLE `prod_users` (
`p_user_id` INT(11) NOT NULL AUTO_INCREMENT,
`p_user_name` VARCHAR(200) NOT NULL DEFAULT ''
`p_comp_name` VARCHAR(300) NOT NULL DEFAULT '',
PRIMARY KEY (`p_user_id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM
Each time a user signs up, he'll provide a company name as well.
There's another table called prod_profiles, which stores profile details like phone nos. fax nos. etc.
CREATE TABLE `prod_profiles` (
`pf_gen_id` INT(11) NOT NULL AUTO_INCREMENT,
`pf_user_id` INT(11) NOT NULL DEFAULT '0',
`pf_user_name` VARCHAR(200) NOT NULL DEFAULT ''
`pf_comp_name` VARCHAR(300) NOT NULL DEFAULT '',
PRIMARY KEY (`pf_gen_id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM
When a new user signs up and his details are added to prod_users, is it possible to automatically add his new user_id, user_name and comp_name details to prod_profile using MySql itself? Since each user will have a new p_user_id and we wont know it, it'll be difficult using php. Can this be achieved inside MySql itself without any problems?
It isn't difficult using PHP, since you have the LAST_INSERT_ID() available for use, be it via mysql_insert_id() or mysqli::$insert_id, PDO::lastInsertId() or whatever your API provides. As long as you call the two INSERT statements in immediate succession on the same script (it is connection dependent), MySQL will supply the correct p_user_id.
However, you can use an AFTER INSERT trigger to force MySQL to create the new row automatically:
CREATE TRIGGER build_profile AFTER INSERT ON prod_users
FOR EACH ROW
BEGIN
INSERT INTO prod_profiles
(pf_user_id, pf_user_name, pf_comp_name)
VALUES (NEW.p_user_id, NEW.p_user_name, NEW.p_comp_name)
END
Review the MySQL CREATE TRIGGER syntax reference for full details and options.
You can use the next mysql function: LAST_INSERT_ID(); which returns the last auto increased id.
Therefore , add a user and then add a prod_profile , while pf_user_id value will be the returned value of last_insert_id().
INSERT INTO `prod_users`(`p_user_name`,`p_comp_name`) VALUES('Dan' , 'Stackover')
INSERT INTO `prod_profiles`(`pf_user_id`,`pf_user_name`,`pf_comp_name`) VALUES(LAST_INSERT_ID(),'Dan','Stackover')
Please notice: I have to say , that storing the username and company_name twice for the same user in two different tables is a reall waste...
Consider re-thinking about your DB structre and logic.

Database Tables - normalized enough?

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.