Table design when using authorization with jdbcrealm in Glassfish v3 - mysql

When using jdbcrealm in Glassfish v3 how strictly must I follow the recommendations regarding tables? Currently I have the following setup:
CREATE TABLE roles (
id INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT,
username VARCHAR(255) NOT NULL,
rolename VARCHAR(255) NOT NULL,
);
CREATE TABLE users (
id INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT,
username VARCHAR(255) PRIMARY KEY NOT NULL,
password VARCHAR(255) NOT NULL,
firstname VARCHAR(255),
lastname VARCHAR(255),
email VARCHAR(255),
status VARCHAR(255),
role_id INTEGER,
CONSTRAINT FOREIGN KEY(role_id) REFERENCES roles(id)
);
Is it possible to use this setup without changing anything to create a jdbcrealm or must I change my tables?
Thanks in advance!

Have you tried it? It seems ok. The strange thing with the jdbcRealm is that it expects an unnormalized database, one would like something more like:
user (userid, username, passw, ...)
security_group (security_groupid, name)
user_in_group (user_in_groupid, userid, security_groupid)
Wich is more normalized. However this setup does not work. But if you're like me and think this should work take a look at the lovely custom Flexible JDBC Realm. It worked for me.

Related

MySQL Error with CREATE TABLE

I am new to creating/testing/working with MySQL.
In this I have created a database and have used the command to USE the Database, however when trying to create a table, Error Code:1064 keeps coming up.
I have no previous tables in this database, this would be the first table.
I am unsure where the error is and would greatly appreciate it if someone could help me identiy the error and the reason why?
CREATE TABLE Customers(
customerNumber INT NOT NULL,
firstName VARCHAR(60),
lastName VARCHAR(60),
address VARCHAR(50) NOT NULL,
city VARCHAR(20) NOT NULL,
state ENUM('QLD','VIC','NSW','WA','TAS','NT','SA') NOT NULL,
postCode INT(4) NOT NULL,
region VARCHAR(60),
email VARCHAR(254),
PRIMARY KEY(customerNumber),
FOREIGN KEY(customerNumber)
);
A foreign key must reference another table.
The other table must exist before you can reference it in a foreign key.
I contributed to a checklist for foreign keys in this post:
https://stackoverflow.com/a/4673775/20860

Confusing error regarding mysql table creation

This is the SQL line I'm using to create the table:
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(255),
surname VARCHAR(255),
email VARCHAR(255) UNIQUE,
username VARCHAR(255) UNIQUE,
passwordHash CHAR(60),
admin BIT
)
Should be pretty generic, however, I'm getting the error "Specified key was too long; max key length is 767 bytes"
Which just leaves me wondering, what key is too long? The longest is supposedly 255B, no?
It depends on your server default encoding. For instance, in UTF-8 you use three bytes for each character.
The issue comes from 'UNIQUE' constraint on VARCHAR(255) columns.
Here Try This out:-
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
firstname VARCHAR(255),
surname VARCHAR(255),
email VARCHAR(255) UNIQUE,
username VARCHAR(255) UNIQUE,
passwordHash CHAR(60),
admin BIT,
PRIMARY KEY (id),
CONSTRAINT user_info UNIQUE(email,username)
);
i think this will work

database using foreign keys

please excuse me if i'm doing things wrong, as I am new to this forum.. I am trying to figure out what columns to have for foreign keys... My teacher redid my database and i can't understand what to do. Here is my ERD: http://s1.postimg.org/3l2j6rh4v/Picture.png
I have looked up tutorials but I can't seem to find out how to use them..
Here is my MySQL code:
DROP TABLE PaymentType;
DROP TABLE ProjectType;
DROP TABLE Projects;
DROP TABLE Payment;
DROP TABLE Customer;
CREATE TABLE Customer
(
Customer_ID varchar(100) NOT NULL,
FName varchar(15) NOT NULL,
LName varchar(20) NOT NULL,
CustAddress varchar(20) NOT NULL,
CustCity varchar(30) NOT NULL,
CustState varchar(20),
CustZip char(5),
CustBal numeric(7,2) NOT NULL,
PRIMARY KEY (Customer_ID)
);
CREATE TABLE Payment
(
Payment_ID varchar(100) NOT NULL,
PaymentType varchar(15),
Date date NOT NULL,
AmntPaid numeric(7,2) NOT NULL,
PRIMARY KEY (Payment_ID)
);
CREATE TABLE Projects
(
Project_ID varchar(100) NOT NULL,
ProjectType varchar(30) NOT NULL,
LaborHrs char(3) NOT NULL,
Date date NOT NULL,
PRIMARY KEY (Project_ID)
);
CREATE TABLE ProjectType
(
Project_ID varchar(100) NOT NULL,
ProjectDesc varchar(100) NOT NULL,
PRIMARY KEY (Project_ID)
);
CREATE TABLE PaymentType
(
Payment_ID varchar(100) NOT NULL,
PaymentDesc varchar(100) NOT NULL,
PRIMARY KEY (Payment_ID)
);
Hopefully I didn't do anything wrong, thanks!
1) You should change your types for the id columns. Using varchar as id column should be avoided, as this will just blow off the performance (+ some other problems which might occur). Using any type of int (int, tinyint,..) would be much better.
2) The table "ProjectType" should have a column "ProjectType_ID" instead of "Project_ID" - same goes for the PaymentType ("PaymentType_ID").
3) Rename the fields in "Project" and "Payment" table as well.
4) The code for foreign-keys will look like:
ALTER TABLE Project
ADD CONSTRAINT Project_ProjectType
FOREIGN KEY (ProjectType_ID)
REFERENCES ProjectType(ProjectType_ID);
Do the same with Payment table.
Important: add "alter table"-command to the end of your sql file, so all tables are created
Important: your database schema should be innodb, or any other schema which supports foreign-keys (MyIsam does NOT support foreign-keys)
5) For the relation between Customer and Projects you will need an extra table (so one project can have multiple users | might be a change to your erd). A cross-relation table (called something Like CustomerProject) with fields "Project_ID" and "Customer_ID". Then add a foreign-key to the project table and add a foreign-key to customer table. (extra points for adding a unique key to "Project_ID" + "Customer_ID")
For the payment and user, just add a "Customer_ID" field in "Payment" table and add a foreign-key as explained in #4.
(offtopic): your naming convention is a bit wierd. Mixing underscore and camelcase should be avoided. You can just stick to camelcase - even for your id fields - but this is just a personal opinion

Creating tables for user authentication - room for improvements?

At the moment I'm developing a web application. For that, I need to create a database for user authentication.
I have something like the following in mind:
create table users
(
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(100) NOT NULL,
password VARCHAR(60) NOT NULL,
PRIMARY_KEY(id),
UNIQUE(username)
);
create table roles
(
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
role VARCHAR(100) NOT NULL,
PRIMARY_KEY(id),
UNIQUE(role)
);
create table user_roles
(
user_id SMALLINT UNSIGNED NOT NULL,
role_id SMALLINT UNSIGNED NOT NULL,
PRIMARY_KEY(user_id)
UNIQUE (user_id, role_id),
);
Passwords are fixed size but I use varchar because I've read somewhere that in a table where you have both char and varchar columns, the char columns get converted to varchar.
Also, would it be beneficial to use FOREIGN KEY CONSTRAINTS?
Don't use SMALLINTs for IDs. Seriously. Why would anybody do that!? Use a larger integer type.
The primary key on user_roles isn't going to work. Make (user_id, role_id) the primary key and put separate (non-unique) indexes on the fields you will be querying on.
You could add foreign keys that link user_roles to the other tables. If you use ON DELETE CASCADE, it'll even delete the stale links if you ever delete a user or a role.

How should I structure my MySQL database?

First of all, sorry if this might be a stupid question. I'm very new to the world of MySQL, so...
Anyway, my question is this: I'm planning on having a database that deals with (for now) two types of users, let's say Admins and Users. My aim is to have ONE table containing all users, aptly named "users". Below is a rough outline of my MySQL command (which I haven't tested yet so errors are likely):
CREATE TABLE users {
user_id int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_type int NOT NULL REFERENCES user_types(user_type_id),
ssn char(10) NOT NULL,
password varchar(40) NOT NULL,
first_name varchar(30) NOT NULL,
last_name varchar(30) NOT NULL,
address varchar(80) NOT NULL
} engine = InnoDB;
The "user_type" column above will refer to another table called "user_types", which lists the different user types for the website (I'm doing this for the sake of having the option to add more user types later):
CREATE TABLE user_types {
user_type_id int UNSIGNED NOT NULL PRIMARY KEY,
user_type_desc varchar(10) NOT NULL
} engine = InnoDB;
INSERT INTO user_types (user_type_id, user_type_desc) VALUES(1,'Admin'),(2,'User');
My aim is to link "Users" with "Admins"; one "User" (child) can have one "Admin" (parent), but one "Admin" (parent) can have several "Users" associated (children). The goal for me is to create a simple appointment calendar, and for that I need to connect users with their admins (one-to-one relationships in the sense that the appointment is between one user and one admin). Now the question is:
1) Is it possible to achieve this by having ONE table for all users? If so, how do I do it in a good way? Right now I was thinking of creating a table called "assignments":
CREATE TABLE assignments {
assign_id int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
patient_id int NOT NULL REFERENCES users(user_id),
doctor_id int NOT NULL REFERENCES users(user_id)
} engine = InnoDB;
But the above code looks strange to me; can I do that kind of foreign key linking to the same table without any dangers? Below is also the SQL 'code' for the "appointments" table:
CREATE TABLE appointments {
appointment_id int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
assign_id int FOREIGN KEY REFERENCES assignments(assign_id),
date_time datetime NOT NULL,
description varchar(200) NOT NULL
};
That is, every entry in the "appointments" table points to a certain assignment between an "Admin" and a "User".
2) How can I achieve the one-to-many relationship between "Admins" and "Users" in an easy way, or rather, a proper way?
Any help or suggestions would be greatly appreciated, and sorry if these questions are stupid!
Your proposed assignments table would work if you had a many-to-many relationship between Users and Admins. Since you've described the relationship as 1-to-many (one Admin may have many Users), I would simply add an admin_id column to your users table and make it a self-referencing foreign key back to the users table.
CREATE TABLE users {
user_id int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_type int NOT NULL REFERENCES user_types(user_type_id),
ssn char(10) NOT NULL,
password varchar(40) NOT NULL,
first_name varchar(30) NOT NULL,
last_name varchar(30) NOT NULL,
address varchar(80) NOT NULL,
admin_id int REFERENCES users(user_id)
} engine = InnoDB;
In the users table add admin_userid that References users(user_id)
That way, each user points back to users table to the admin user they belong to.
Using this column a doctor can list all his patients and the assignements table can be used with appointments.
But will a certain user ALWAYS get a meeting with the same doctor/admin?
What about vacations?