Your usernames are to be unique. Good, they should be. But now you seem to think that Username
would make a good primary key. Not necessarily. One important characteristic of a PK is stability. Unless you wish to implement a "one you've chosen a username you're stuck with it forever" policy (and that is a decidedly user-unfriendly policy), someone may want to change their username. Doing so when that username is scattered all over the database is going to be difficult.
I am not a fan of design rules that demand a surrogate key for every table. But typically 50% or more of tables should have surrogate keys. This is one of them.
And I certainly hope that when you say the login table will contain the password, you do mean the hash of the password, don't you?
@ypercube speaks for all of us about the "for each question, there will be separate table" idea. Not good.
Now as for the user's code. For that you have choices. You don't mention the target DBMS (if you even have one at this point) but some handle text
or clob
fields better than others. The question of handling actual disk files is one you will have to research yourself. Will those files reside in a file server, within a version control system, just a dedicated folder on some disk somewhere? In any case, what are the OS-based and/or network access privileges that will be needed? You get the idea. There are a lot of questions unrelated to databases that must be answered.
Not to say that one is superior to the other, but unless you or someone on your team has done this before, you may want to start with storing the code in the database. That will probably get you started faster and you can move to system files (if you determine it to be the better option) more or less at your leisure.
I have a rather ugly approach that will strip alphanumeric characters from a user variable
STRIPPING ALPHAS
SET @st='r1+o2l-3a4*n5d6o7';
SELECT (@st:=REPLACE(@st,ch,'')) FROM
(
SELECT (x*10+y) ndx,SUBSTR(chars,x*10+y,1) ch FROM
(SELECT 'abcdefghijklmnopqrstuvwxyz' chars) L,
(SELECT 0 x UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
UNION SELECT 5 x UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) X,
(SELECT 0 y UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
UNION SELECT 5 x UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Y
WHERE SUBSTR(chars,x*10+Y,1)<>'' ORDER BY SUBSTR(chars,x*10+y,1)
) alpha;
SELECT @st;
STRIPPING ALPHAS EXECUTED
mysql> SELECT (@st:=REPLACE(@st,ch,'')) FROM
-> (
-> SELECT (x*10+y) ndx,SUBSTR(chars,x*10+y,1) ch FROM
-> (SELECT 'abcdefghijklmnopqrstuvwxyz' chars) L,
-> (SELECT 0 x UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
-> UNION SELECT 5 x UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) X
-> (SELECT 0 y UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
-> UNION SELECT 5 x UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Y
-> WHERE SUBSTR(chars,x*10+Y,1)<>'' ORDER BY SUBSTR(chars,x*10+y,1)
-> ) alpha;
+---------------------------+
| (@st:=REPLACE(@st,ch,'')) |
+---------------------------+
| r1+o2l-34*n5d6o7 |
| r1+o2l-34*n5d6o7 |
| r1+o2l-34*n5d6o7 |
| r1+o2l-34*n56o7 |
| r1+o2l-34*n56o7 |
| r1+o2l-34*n56o7 |
| r1+o2l-34*n56o7 |
| r1+o2l-34*n56o7 |
| r1+o2l-34*n56o7 |
| r1+o2l-34*n56o7 |
| r1+o2l-34*n56o7 |
| r1+o2-34*n56o7 |
| r1+o2-34*n56o7 |
| r1+o2-34*56o7 |
| r1+2-34*567 |
| r1+2-34*567 |
| r1+2-34*567 |
| 1+2-34*567 |
| 1+2-34*567 |
| 1+2-34*567 |
| 1+2-34*567 |
| 1+2-34*567 |
| 1+2-34*567 |
| 1+2-34*567 |
| 1+2-34*567 |
| 1+2-34*567 |
+---------------------------+
26 rows in set (0.00 sec)
STRIPPING ALPHAS RESULT
mysql> SELECT @st;
+------------+
| @st |
+------------+
| 1+2-34*567 |
+------------+
1 row in set (0.00 sec)
mysql>
STRIPPING NUMERICS
SET @st='r1+o2l-3a4*n5d6o7';
SELECT (@st:=REPLACE(@st,ch,'')) FROM
(
SELECT x+1 ndx,SUBSTR(chars,x+1,1) ch FROM
(SELECT '0123456789' chars) L,
(SELECT 0 x UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
UNION SELECT 5 x UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) X
) numerics;
SELECT @st;
STRIPPING NUMERICS EXECUTED
mysql> SET @st='r1+o2l-3a4*n5d6o7';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT (@st:=REPLACE(@st,ch,'')) FROM
-> (
-> SELECT x+1 ndx,SUBSTR(chars,x+1,1) ch FROM
-> (SELECT '0123456789' chars) L,
-> (SELECT 0 x UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
-> UNION SELECT 5 x UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) X
-> ) numerics;
+---------------------------+
| (@st:=REPLACE(@st,ch,'')) |
+---------------------------+
| r1+o2l-3a4*n5d6o7 |
| r+o2l-3a4*n5d6o7 |
| r+ol-3a4*n5d6o7 |
| r+ol-a4*n5d6o7 |
| r+ol-a*n5d6o7 |
| r+ol-a*nd6o7 |
| r+ol-a*ndo7 |
| r+ol-a*ndo |
| r+ol-a*ndo |
| r+ol-a*ndo |
+---------------------------+
10 rows in set (0.00 sec)
STRIPPING NUMERICS RESULT
mysql> SELECT @st;
+------------+
| @st |
+------------+
| r+ol-a*ndo |
+------------+
1 row in set (0.00 sec)
mysql>
STRIPPING ALPHANUMERICS
SET @st='r1+o2l-3a4*n5d6o7';
SELECT (@st:=REPLACE(@st,ch,'')) FROM
(
SELECT (x*10+y) ndx,SUBSTR(chars,x*10+y,1) ch FROM
(SELECT 'abcdefghijklmnopqrstuvwxyz0123456789' chars) L,
(SELECT 0 x UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
UNION SELECT 5 x UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) X,
(SELECT 0 y UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
UNION SELECT 5 x UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Y
WHERE SUBSTR(chars,x*10+Y,1)<>'' ORDER BY SUBSTR(chars,x*10+y,1)
) alphanumeric;
SELECT @st;
STRIPPING ALPHANUMERICS EXECUTED
mysql> SET @st='r1+o2l-3a4*n5d6o7';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT (@st:=REPLACE(@st,ch,'')) FROM
-> (
-> SELECT (x*10+y) ndx,SUBSTR(chars,x*10+y,1) ch FROM
-> (SELECT 'abcdefghijklmnopqrstuvwxyz0123456789' chars) L,
-> (SELECT 0 x UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
-> UNION SELECT 5 x UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) X,
-> (SELECT 0 y UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
-> UNION SELECT 5 x UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Y
-> WHERE SUBSTR(chars,x*10+Y,1)<>'' ORDER BY SUBSTR(chars,x*10+y,1)
-> ) alphanumeric;
+---------------------------+
| (@st:=REPLACE(@st,ch,'')) |
+---------------------------+
| r1+o2l-3a4*n5d6o7 |
| r+o2l-3a4*n5d6o7 |
| r+ol-3a4*n5d6o7 |
| r+ol-a4*n5d6o7 |
| r+ol-a*n5d6o7 |
| r+ol-a*nd6o7 |
| r+ol-a*ndo7 |
| r+ol-a*ndo |
| r+ol-a*ndo |
| r+ol-a*ndo |
| r+ol-*ndo |
| r+ol-*ndo |
| r+ol-*ndo |
| r+ol-*no |
| r+ol-*no |
| r+ol-*no |
| r+ol-*no |
| r+ol-*no |
| r+ol-*no |
| r+ol-*no |
| r+ol-*no |
| r+o-*no |
| r+o-*no |
| r+o-*o |
| r+-* |
| r+-* |
| r+-* |
| +-* |
| +-* |
| +-* |
| +-* |
| +-* |
| +-* |
| +-* |
| +-* |
| +-* |
+---------------------------+
36 rows in set (0.00 sec)
STRIPPING ALPHANUMERICS RESULT
mysql> SELECT @st;
+------+
| @st |
+------+
| +-* |
+------+
1 row in set (0.00 sec)
mysql>
EPILOGUE
This SELECT query is meant to hold up to 100 characters for stripping
You can replace (SELECT 'abcdefghijklmnopqrstuvwxyz0123456789' chars) L,
with any list of characters you wish to strip from a user variable.
GIVE IT A TRY !!!
Best Answer
Storing: Use a field with datatype
BINARY(64)
orCHAR(64) CHARSET ascii COLLATE ascii_bin
.Generating:
This is not an SQL question because it should not be done in the database. It should be done in the UI layer that receives and checks passwords, etc.
So, given that you should write this in Perl/PHP/VB/Java, you have much stronger tools with which to generate the corporate password.
Of what use is a password that everyone knows? As soon as a disgruntled employee gets fired, the password may become known to the world.
I'm serious -- some things do not belong in SQL; instead they should be in the code that access the database.
But if you must do it (for the class) in SQL, consider creating a table of the possible characters, one per row, plus another table of (at least) 64 distinct integers. Then use a
JOIN
,GROUP_CONCAT
,ORDER BY RAND()
,LIMIT 64
, and probably a subquery to get the INTs.