job seek website database design [closed] - mysql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am creating a job seek website with PHP and MySQL, one question is how to design the database better? The basic function of the website is that 'jobseekers' can login and search jobs, upload CVs, and 'employers' can login and post jobs, and browser CVs. Currently I just created 2 tables:
-- Table structure for table users
to analyze the table sturctures for a job seek website(using MySQL and PHP) [on hold]
-- user_type: 0 - jobseekers
-- 1 - employers
-- 2 - administrator
CREATE TABLE users (
user_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
first_name VARCHAR(20) NOT NULL,
last_name VARCHAR(40) NOT NULL,
email VARCHAR(80) NOT NULL,
pass CHAR(40) NOT NULL,
user_type TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
active CHAR(32),
last_login DATETIME NOT NULL,
registration_date DATETIME NOT NULL,
PRIMARY KEY (user_id),
UNIQUE KEY (email),
INDEX login (email, pass)
) ENGINE = INNODB;
-- Table structure for table jobs
CREATE TABLE jobs (
job_id INT(11) NOT NULL AUTO_INCREMENT,
title VARCHAR(200) NOT NULL,
description text NOT NULL,
county VARCHAR(30) NOT NULL,
PRIMARY KEY (job_id)
) ENGINE = MYISAM ;
But I feel just two tables might not be enough, and the user table maybe need to be broke down. Any suggestion how to improve the design?

Perhaps you may want 4 tables;
2 to store the user details
jobseeker_details_table; ( name, address, phonenumber, CV etc)
employer_details_tabel; (name, address, companyname, phone, etc)
than 2 more tables, one for the jobs jobseekers have applied for, and one for the jobs employers have posted - as employers are likely to post more than one job position, and jobseekers and likely to apply for many different jobs, so;
jobs_applied_table; (id, jobid, status, etc)
employer_posted_jobs; (jobid, position_details, date_posted, status, etc)
hope that helps / gives you something to think about.
good luck

Related

Select Exchange Rate based on Currency and Date [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I've looked around for a solution to this, but at least I was unable to find anything which would at least be similar to my case.
I need to select the exchange rate, based on the date a product was purchased.
Let me try and explain.
I have a table with Currencies:
CREATE TABLE `tblCurrencies` (
`CurrID` int(11) NOT NULL AUTO_INCREMENT,
`CurencySymbol` varchar(1) DEFAULT NULL,
`CurrencyCode` varchar(3) DEFAULT NULL,
`CurrencyDescription` varchar(100) DEFAULT NULL,
PRIMARY KEY (`CurrID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
A table with Exchange Rates:
CREATE TABLE `tblExchRates` (
`ExcID` int(11) NOT NULL AUTO_INCREMENT,
`CurrKey` int(11) DEFAULT NULL,
`Date` date DEFAULT NULL,
`Exchange` decimal(11,3) DEFAULT NULL,
PRIMARY KEY (`ExcID`),
KEY `CurrKey` (`CurrKey`),
CONSTRAINT `tblExchRates_ibfk_1` FOREIGN KEY (`CurrKey`) REFERENCES `tblCurrencies` (`CurrID`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=111 DEFAULT CHARSET=utf8;
And a table with Products (note my products are listed in numbers in the table, which is OK in my case):
CREATE TABLE `tblProducts` (
`ProductID` int(11) NOT NULL AUTO_INCREMENT,
`Contract` int(11) DEFAULT NULL,
`Product` int(11) DEFAULT NULL,
`Type` varchar(100) DEFAULT NULL,
`Currency` int(11) DEFAULT NULL,
`Amount` decimal(10,0) DEFAULT NULL,
`PurchaseDate` datetime DEFAULT NULL,
PRIMARY KEY (`ProductID`),
KEY `Contract` (`Contract`),
KEY `Currency` (`Currency`),
CONSTRAINT `tblShopCart_ibfk_2` FOREIGN KEY (`Currency`) REFERENCES `tblCurrencies` (`CurrID`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `tblShopCart_ibfk_1` FOREIGN KEY (`Contract`) REFERENCES `tblContracts` (`ContractID`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3155 DEFAULT CHARSET=utf8;
In the Exchange Rates table, as an example, values are set like this:
CurrKey Date Exchange
1 15-01-2017 0.850
1 31-01-2017 0.856
1 02-02-2018 0.918
1 18-02-2018 0.905
2 04-02-2018 1.765
2 14-02-2018 1.755
And so on...
I want to have a query that select a unique exchange rate based on the date a product was purchased and the currency it was purchased.
In other words, as an example, if I have a product that was purchased on 07-02-2018, the query has to select the exchange rate which is valid in the relevant date rage that matches the purchase date and its currency. In this example, the correct exchange rage for a product purchased on 07-02-2018 which has a currkey of 1 would be 0.918
Please note that exchange rates are set on random dates (as per example above).
I managed to make this query, but it is not precise, as it sometimes returns two or more results (due to the 10 days range I set), whereas I only need 1 result:
SELECT
tblExchRates.Exchange
FROM
tblCurrencies
INNER JOIN tblExchRates ON tblExchRates.CurrKey = tblCurrencies.CurrID
WHERE
tblCurrencies.CurrencyCode = "EUR" AND
tblExchRates.Date BETWEEN (tblProducts.PurchaseDate - INTERVAL 10 DAY) AND (tblProducts.PurchaseDate + INTERVAL 10 DAY)
For a fairly simple solution you can do
SELECT
p.*
,(SELECT TOP 1 er.Exchange
FROM tblExchRates AS er
INNER JOIN tblCurrencies AS c ON er.CurrKey = c.CurrID AND c.CurrencyCode = 'EUR'
WHERE er.Date <= p.PurchaseDate
ORDER BY er.Date DESC) AS ExchangeRate
FROM
tblProducts AS p
Another option, if you have control over the schema then changing your exchange rates table to have a DateFrom and DateTo rather than just a date would then mean you can simply find the correct exchange rate using the BETWEEN keyword.
I am a beginner myself so no guarantees on correctness. I believe you have to use a certain application programming language along with SQL, for example PHP. Still, I will outline the basic steps I would take.
1. Assign the purchase currency ID and purchase date to variables using a simple SELECT statement. Assume I give the ID to targetID and date to targetDate.
2. SELECT MIN(Date) FROM tblExchRates WHERE Date <= targetDate AND CurrKey =targetID; //Select most recent date whose range includes the date of purchase among the matching currency IDs. Assign the result of this statement to another variable. Assume I used the variable dateRange.
3. SELECT Exchange FROM tblExchRates WHERE Date = targetDate; //Find the exchange rate of the selected date.
Note that there are many ways to do this. For example, you could use table JOINS (refer to this link: https://www.w3schools.com/sql/sql_join.asp ) or select columns from different tables in just one SQL statement (refer to this Stack overflow question: MySQL Select all columns from one table and some from another table). Last, you can use SQL to create variables (refer to this question: Set the variable result, from query) and then perform operations.

Correct Database schema for Question/Answer system

I am trying to build a system where the user can add a question and the other users can be commenting on his question or voting.
The main functions are :
1. user can add a question.
2. user can comment on his or other users questions.
3. user can replay (comment) on his or other users comments.
4. user can vote on other users questions.
The data schema that I build is as following (Examples):
Question: {
id: "question_Q1",
title: "How to learn python in one week?",
body: "I am trying to learn a new language .............",
images: {"python1.png","python2.png","python3.png","python5.png"},
tags: {"python","programing"},
user_id: "user_123456",
voters: [
{id:"user_123457", username:"John F.M"},
{id:"user_123458", username:"Sarah K.P"}
],
create_timeDate: "02/01/2018 11:00 pm",
update_timeDate: "21/02/2018 10:12 am"
comments: [
{ id: "comment_c1",
body:"you can learn it from ....",
images: null,
create_timeDate: "12/04/2018 11:00 pm",
update_timeDate: "15/04/2018 10:12 am",
replay: null},
{ id: "comment_c2",
body:"watch youtube for more information .....",
images: {"youtube.gif"},
create_timeDate: "19/04/2018 09:43 pm",
update_timeDate: "25/04/2018 11:10 pm",
replay: [
{ id: "replay_comment_c1",
body:"ohh thanks",
images: null,
create_timeDate: "14/04/2018 01:00 am",
update_timeDate: "20/04/2018 03:12 am",
replay: null
},
]
}
]
}
Is it correct what I am doing?
And what about voting? I don't know how to implement in it in my DB schema. I want to do the same voting system in the stack overflow but only on questions (without on comments).
I would create these tables: Questions, Images, QuestionTags, QuestionVoters, QuestionTag and Comments.
Table Question:
QuestionID,
title,
body,
user_id,
Table Questionvoters:
VoteID,
QuestionID (foreign Key to the Question table),
UserID
Table QuestionTagMapping:
QuestionID (foreign key to the Question table)
TagID (foreign key to the Tags table)
Table QuestionTag:
TagID
Tag
Table Comments:
Commentid,
QuestionID (foreign key to the Question table),
CommentReplyID: (if a comment replies to another comment put the id of this comment there),
body,
create_timeDate,
update_timeDate
Table Images:
ID (ID of the Comment or the Question),
Image
Update
Here is an example how i would solve your problem. I used a SQL Server database. The explanations are in the code written in comments.
--store the user information here, you don't need to store any pw if you want
--... we only need the iduser for our example
CREATE TABLE sUser
(
iduser varchar(100) PRIMARY KEY,
username varchar(100) not null,
--that could be other columns...
/*
--I have not stored any Password Hashes in DB, i am actually not sure if 1000 is the right length
pwhash varchar(1000),
email varchar(256),
*/
)
--store the Question and Comment data in this table
--I don't store Images or Tags in this table because I do no want to have multiple rows per post.
--If you had multiple rows for one post, it would cause problems when you update the data
CREATE TABLE Post
(
--I would not make the post id a varchar but in your example you defined a key for example like this 'question_Q1'
IDPost varchar(100) Primary Key,
--is only filled if the post is a question
title varchar(100) null,
body text not null,
iduser varchar(100) not null,
--create the link to which question or comment a comment belongs
ReplyID varchar(100) null,
create_timeDate datetime2 not null,
update_timeDate datetime2 not null,
--creates an reference to the table itself, to a "mother" question or comment
FOREIGN KEY (ReplyID) REFERENCES Post(IDPost),
--creates a reference to the table users, so you can only insert a question or comment if the specified user exists
FOREIGN KEY (iduser) REFERENCES sUser(iduser),
)
--stores votes
CREATE TABLE QuestionVoter
(
--with this column you can map the vote to the Question
IDPost varchar(100) not null,
--0 if the vote is negative, 1 if the vote is positive
Vote bit not null,
iduser varchar(100) not null,
PRIMARY KEY(IDPost,iduser),
--creates a reference to the table Post, so you can only insert a vote in this table if the PostID --> the Question exists in the Post table
FOREIGN KEY (IDPost) REFERENCES Post(IDPost)
)
--here you can specify a set of Tags
CREATE TABLE QuestionTag
(
IDTAG int Primary Key,
Tag varchar(100) not null
)
--create a mapping from a Question to the votes, the benefit for creating a mapping Table from the table Posts to the table QuestionTag,
--is that you can specify a set of gags and you don't have to store gags multipile times.
CREATE TABLE QuestionTagMapping
(
--with this column IDPost you map the QuestionTag to the question
IDPost varchar(100) not null,
IDTAG int not null,
PRIMARY KEY(IDPost, IDTAG),
FOREIGN KEY (IDPost) REFERENCES Post(IDPost),
FOREIGN KEY (IDTAG) REFERENCES QuestionTag(IDTAG)
)
--store your ImagePath in this table
CREATE TABLE Images
(
--this column is again for the mapping to the post
IDPost varchar(100) NOT NULL,
ImagePath varchar(256) not null,
PRIMARY KEY(IDPOST, ImagePath),
FOREIGN KEY (IDPost) REFERENCES Post(IDPost)
)
--example insert
--in your case i would not write plain sql, use a ORM Framework like JPA, Entity FrameWork Core to persist the data, but for this example its more then enough
--insert the Users
insert into sUser
values('user_123456','USER'),('user_123457','John F.M'),('user_123458','Sarah K.P')
--insert the Question
insert into Post
values('question_Q1', 'How to learn python in one week?', 'I am trying to learn a new language .............', 'user_123456',null,getdate(),getdate())
--insert the images for the Question
insert into Images
values('question_Q1','python1.png'),('question_Q1','python2.png')
--insert the votes for the question
insert into QuestionVoter
values('question_Q1', 1,'user_123457'),('question_Q1',1,'user_123458') --etc.
--specify QuestionTags
insert into QuestionTag
values(1, 'python'),(2, 'programming')
--select * from QuestionTag
--assagin the tags to a question via the QuestionTagMapping Table
insert into QuestionTagMapping
values('question_Q1',1),('question_Q1',2)
--insert comments
insert into Post
values('comment_c1',/*title is null becouse comments dont have titles*/ null, 'you can learn it from ....','user_123457'
,/*insert the ReplyID to make a reference to question where the comment was postet*/ 'question_Q1',/*GETDATE() is just for example that the field have values*/GETDATE(), GETDATE())
,('comment_c2',null, 'watch youtube for more information .....','user_123457', 'question_Q1',GETDATE(), GETDATE())
,('replay_comment_c1',null, 'ohh thanks','user_123456', 'comment_c2',GETDATE(), GETDATE())
--Example queries
--Get the amount of votes
SELECT p.IDPost, count(*) as AmountVotes, sum(cast(v.Vote as int)) as PositivVotes, sum(IIF(v.Vote = 0,1,0)) as NegativVotes
FROM Post p
LEFT JOIN QuestionVoter v on p.IDPost = v.IDPost
WHERE p.IDPost = 'question_Q1'
GROUP BY p.IDPost
--GET the comments for a question
SELECT *
FROM Post q
--JOIN via the ReplayID the comments with questions or subcomments
LEFT JOIN Post c on q.IDPost = c.ReplyID
--get the sub comments with another join on ReplayID of the subcomment and the IDPost of the comments
LEFT JOIN Post sc on c.IDPost = sc.ReplyID
WHERE q.IDPost = 'question_Q1'

Multi level login table design [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I need to create a multi level application where user detail are stored in a mysql table called Users.
Now I need to allow user to create sub-user or client account. So there will be admin, user and client account that can login in the site.
My question is: how can I group the admin and the his own created sub-user and client?
I should create a second table with the not-admin details? or is better to have the client and user in the same table of admin and then create a self relationship on the table?
Here's more or less how I've done it in the past:
actions
id unsigned int(P)
description varchar(50) // Delete users, Edit something, etc.
roles
id unsigned int(P)
site_account_id unsigned int(F site_accounts.id)
description varchar(50) // Client Admin, Client User, etc.
roles_actions
id unsigned int(P)
role_id unsigned int(F roles.id)
action_id unsigned int(F actions.id)
site_accounts
id unsigned int(P)
name varchar(50) // Client 1, Client 2, etc.
users
id unsigned int(P)
site_account_id unsigned int(F site_accounts.id)
username varchar(32)
password varbinary(255)
email varchar(255)
users_roles
id unsigned int(P)
user_id unsigned int(F users.id)
role_id unsigned int(F roles.id)
You'll create a role for "Client Administrators" and this role will have all the permissions that a client can possibly have. Then you'll create a site account whenever you sign up a new client and you'll assign them the role of "Client Administrator".
You'll need to write the code that lets them create their own roles (which will be associated with their site_account_id) and also let them assign any of their actions to each of those new roles. This gives them complete control over what roles they want and what permissions each role has.
You'll also need to write the code that lets them add/update/delete users (again, each of those users will be associated with their site_account_id).
This makes it easy for you to see what roles/users belong to each of your clients and whenever you lose one you can delete all of their data by simply deleting their site_accounts record.
This is just a rough example. There's a lot more that can go into something like this so you'll have to figure out how fine-grained you want it to be.
Keep all accounts in the same table and add a parentAccount column to store the primary key of the account's parent.

In MySQL, how to "join" three tables

I've seen a good amount of threads on "how to join more than two tables" but none of those threads seem to solve my problem.
I have three tables:
teams, persons and payfiles
teams Table looks like this:
DROP TABLE IF EXISTS `teams`;
CREATE TABLE IF NOT EXISTS `teams` (
`team_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`leader` varchar(32) NOT NULL,
PRIMARY KEY (`team_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=30;`
persons table:
DROP TABLE IF EXISTS `persons`;
CREATE TABLE IF NOT EXISTS `persons` (
`team_id` int(2) DEFAULT '0',
`hash` varchar(32) NOT NULL,
UNIQUE KEY `hash` (`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
payfiles table:
DROP TABLE IF EXISTS `payfiles`;
CREATE TABLE IF NOT EXISTS `payfiles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`hash` varchar(32) NOT NULL,
`deals_passed` int(2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1298 ;
Tables have much more columns, but I trimmed them for the sake of simplicity.
teams table contains records in the following way:
1,Team 1,afaf7878af78a
The latter is the team leader's unique hash.
The table persons contains all the personal information, and a unique hash,
For instance
John Doe whose hash is afaf7878af78a who also is the leader of Team 1.
The table payfile also has a "hash" column, that table contains all the information needed to compute employees' checks.
The management team want a general vision of how much the company is making. They want to see how much money every single team is bringing in.
The problem I'm facing here, is trying to group the earnings by "teams"
My best try so far is this
SELECT hash, SUM(deals_passed) as deals FROM payfiles JOIN persons ON persons.hash = payfiles.hash GROUP BY payfiles.hash
but I can't see an optimized way to query the database in order to generate a team by team general vision of earnings without changing the structure of the database.
For instance:
John Doe, and Jane Doe belong to "Team 1" and they brought in $500 and $600 respectively.
I want to generate something like:
"Team 1 brought in $1100"
My alternative is to change the structure of the database, and add a new column to the payfile table. Such column would be team_id so I can query it easily, but the database currently has about 10,000 records so that implies updating the 10K records that didn't consider a team_id column, and make a lot of changes to the GUI, something that I don't really want to do, although if that's the easiest and best option I'll do it.
Thanks!
SELECT
teams.name,
SUM(payfiles.deals_passed) AS team_deals_passed
FROM payfiles
LEFT JOIN persons USING (hash)
LEFT JOIN teams USING (team_id)
GROUP BY teams.team_id
You can use SUM() to the get the total, and use GROUP BY for the team to get each total by team.

MySQL db structure help

I'm working on a quiz project and I want create a mysql structure in such a way that:
questionID: A unique question identification number(primary key)
testID: A unique test identification number(question belongs to this test)(primary key)
questionOrder: The order of the question within the quiz questions, ie this question is n-th question in the quiz. I want this value to come from mysql, so that when I insert a new question to db, I don't have to calculate it
One question can be in multiple different tests.
I have couple of questions:
1) I have the following code but I get:
Incorrect table definition; there can be only one auto column and it must be defined as a key
How can I fix this?
2) This structure doesn't allow a question to belong to multiple quizzes. Any idea to avoid this?
3) Do you think this structure is good/optimum, can you suggest anything better?
CREATE TABLE `quiz_question` (
`questionID` int(11) NOT NULL auto_increment,
`quizID` int(11) NOT NULL default '0',
`questionOrder` int(11) NOT NULL AUTO_INCREMENT,
`question` varchar(256) NOT NULL default '',
`answer` varchar(256) NOT NULL default '',
PRIMARY KEY (`questionID`),
UNIQUE KEY (`quizID`, `questionOrder`),
KEY `par_ind` (`quizID`, `questionOrder`)
) ENGINE=MyISAM;
ALTER TABLE `quiz_question`
ADD CONSTRAINT `0_133` FOREIGN KEY (`quizID`) REFERENCES `quiz_quiz` (`quizID`);
CREATE TABLE `quiz_quiz` (
`quizID` int(11) NOT NULL auto_increment,
`topic` varchar(100) NOT NULL default '',
`information` varchar(100) NOT NULL default '',
PRIMARY KEY (`quizID`)
) ENGINE=MyISAM;
Thanks for reading this.
1) You can only have one AUTO_INCREMENT column per table. It should be a key. Generally, it's part of / is the PK.
2) A 'quiz' would be an entity composed of questions. You should have 3 tables:
1 - quiz_question: quest_id, question, answer
2 - quiz_quiz: quiz_id, topic, info
3 - quiz_fact: quiz_id, quest_id, quest_order
The quiz and question tables hold the per-item (quiz/question) information. The quiz_fact defines how a quiz is composed (this quiz has this question in this order).
3) My only suggestion would be to use Drizzle instead ; ) Seriously though, play with things - 'good enough' often is. If it suits your needs, why tinker? Otherwise you can ask more detailed questions once you have this up and runnning (ie my queries are too slow on such and such operations).
1) Do the order increment yourself. The DB will only do it if it's part of a PK. You might be able to hack it by making a composite key containing the order column but it's not worth it.
2) Rename quiz_question to question (and quiz_quiz to quiz). Make a new quiz-question join table called quiz_question. It should have a quiz ID and a question ID, linking a quiz to a question. As the same question will have different orders on different quizes, put the question order on the new quiz_question. You no longer need a quiz ID on the question table.
Remove AUTO_INCREMENT from the questionOrder field.
As far as having MySQL set the value in the questionOrder field, then do that in a subsequent UPDATE query. Usually, you'd want the administrator of the test, using your admin utility, to be able to adjust the ordering of questions. In that case, you just enter an initial value +1 higher than the highest previous ordering value (on that test). Then, you can let them adjust it something like the manner of adjusting a Netflix queue :)