How to convert a string to a unique number? - php

I have a table like this:
// viewed
+----+------------------+
| id | username_or_ip |
+----+------------------+
As you see, username_or_ip columns keeps username or ip. And its type is INT(11) UNSIGNED. I store IP like this:
INSERT table(ip) VALUES (INET_ATON('192.168.0.1'));
// It will be saved like this: ip = 3232235521
Well, I want to know, is there any approach for converting a string like Sajad to a unique number? (because as I said, username_or_ip just accepts digit values)

int(11) is a 32-bit data type. As such it's just enough to hold an ipv4 address. Your question points that out.
To reversibly convert an arbitary string to a 32-bit data type is difficult: it simply lacks the information storage capacity.
You could use a lookup table for the purpose. Many languages, including php 5.4+, support that using an process called "interning." https://en.wikipedia.org/wiki/String_interning
Or you could build yourself a lookup table in a MySQL table. Its columns would be an id column and a value column. You'd intern each new text string by creating row for it with a unique id value, then use that value.
Your intuition about the slowness of looking up varchar(255) or similar values in MySQL is reasonable. But, with respect, it is not correct. Properly indexed, tables with that kind of data in them are very fast to search.

Related

How to generate id number like 'xxx0000', 'xxx0001'?

This is my table :
| ID |
| xxx0000 |
| xxx0001 |
| xxx0002 |
i want to make my id pattern like that, but i dont know how to generate it?
You have two different pieces of data, so make two different columns.
ID INT NOT NULL AUTO_INCREMENT,
SomethingElse SomeOtherType NOT NULL
What SomethingElse is named and what data type it is would be up to you. xxx doesn't tell us much.
If both of these things combined make up your primary key, you can use a composite key of multiple columns:
PRIMARY KEY (SomethingElse, ID)
The same integrity checks for any primary key will continue to apply, the database will simply check both columns for combined uniqueness.
At this point you have the data you want, now it's just a matter of displaying it how you want. Whether you do that in SQL or in PHP is up to you. Whether you want the application to see them as a single value or see the underlying different values, also up to you.
Selecting them as a single value from SQL could be simple enough. Something like:
SELECT CONCAT(SomethingElse, ID) AS ID FROM ...
If you always want those padded zeroes then this question will help. Other string manipulations you might want to do would also be tackled one at a time (and each could result in its own Stack Overflow question if you need assistance with it).
But the basic idea here is that what you have is a composite value. In a relational database you would generally store the underlying values and perform the composition when querying the data.

Should options be stored as text or integers in a MySQL DB?

I am creating a small database of names that has three columns: ID, Name, Status
The 'status' can be one of three things: waiting, approved, other
My question is, what is the best/most correct way to store the 'status' in the DB? Should it be stored as a varchar string or as a 1, 2, or 3 integer and later translate that to waiting/approved/other when reading from the DB? I hope that makes sense, thanks for any help.
You should have a status table (referred to as a dictionary or lookup table) using a tinyint data type to reference that status. You would use a foreign key constraint. This way you maintain relational and domain integrity. It will allow you to add/change/remove status values without changing table structure.
status
=============
id value
1 Waiting
2 Approved
3 Other
users
====================
id name status_id
1 Bobby 3
Create another table called
statuses with 2 fields
id INT Primary Auto Increment
name varchar(30).
Add your statuses in the user table by integer and reference them with a JOIN.
You can also change status in the users table to status_id it would make more sense.
IMO this is the most appropriate way in
Integers are smaller. Integers can be translated by your app into multiple languages, etc.
Integers good.
Check out ENUM. If not, make sure you're using the right sized integer.
Generally speaking, store those items as text, unless:
You will be searching for them: character searches take longer and are more expensive than numeric (integer) searches
You will need to do 'math' (summation, averages, standard deviations, etc) on them: casting/converting to a number, performing the calculation and then doing something with the results is very process-intensive)
Use numerics with a separate lookup table.
An integer field uses less memory space than a varchar field, so storing your 'status' option as a number will reduce memory usage marginally.
I recommend storing 'status' in an integer and translating it to the corresponding value externally when necessary.
I think they should be stored as what they are: a enum!
Example:
status ENUM('waiting', 'approved', 'other') DEFAULT 'other'

Why in mysql store data like this a:6:{s:5:"title";s:43:}

In mysql database , I find some data store like below:
a:6:{s:5:"title";s:43:"fgjfh";s:8:"province";s:6:"重庆";s:4:"city";s:9:"大渡口";s:8:"location";s:6:"fhfghf";s:9:"starttime";s:11:"09-02
12:00";s:7:"endtime";s:11:"09-02 16:00";}
That's a PHP serialized array. You serialized your array before putting it to the database.
Look for serialize($value) calls in your code if you want to change it.
Update:
Probably your stored data (which is a hash actually) has dynamic fields, and it was too difficult for the creator or he/she didn't care/was lazy to do so/decided that's not important or simply that was not the use case.
But you should consider to rethink your schema and create a correct (3NF) normalization. In this case you will have at least one table which can be like this:
CREATE TABLE data (
id INTEGER PRIMARY KEY, -- or SERIAL if your database supports it
title VARCHAR, -- or TEXT
province_id INTEGER NOT NULL, -- or REFERENCES the provinces table
city_id INTEGER NOT NULL, -- or REFERENCES the cities table
location VARCHAR, -- I do not really know what is this field
starttime TIMESTAMP,
endtime TIMESTAMP
);
And of course your you'll need the provinces and the cities tables as well. With this schema you could use database instructions to work with the stored data if you need so.

Structure of table keys from multiple other column values

I am creating a new database and am thinking about the structure. Earlier I have always used auto-incremented undefined small-INT. There will be plenty of searched performed on some of the tables and the key structured according to the above would seldom be known before and the search would therefore be on a non-key column.
In some tables there are other unique values and there we got no problem just putting that as key, but in some there aren't, thus I am thinking that I instead could construct the key as a put-together of two or more column values in order to create a unique string that I can later search for and ensure better performance.
I haven't heard about this key-construction before so I would like to get some input about if I am thinking correctly here. Thanks!
Here is an example that will illustrate this "put-together"-key:
mysql> CREATE TABLE example (
key VARCHAR(100),
name VARCHAR(50),
category VARCHAR(20),
country VARCHAR(30)
);
name is not unique per se but is unique per category and country (which is ensured at input). The searches will 90% of the time involve these three parameters and thus the code doing the search can put together the key and search for the table id/key. In the 10% of cases when one of the parameters are unknown the search can be made for other columns example on countrydirectly if the user wants to see all rows with country=xyz.
Yes it's completely legal to use two or more columns as a unique identifier, it's called composite key.
http://weblogs.sqlteam.com/jeffs/archive/2007/08/23/composite_primary_keys.aspx

MySQL datatypes?

I'm designing a database in MySQL and PHP for a basic CMS. The CMS will have a front end which will allow sorting and searching. The backend will allow authorized users to upload files.
I'm using PHPMyAdmin and I'd like help setting up my database.
I am open to answers explaining various MySQL datatypes and what they are good for as well . Use common database fields as examples please.
Below is a list of what I'd like. What's missing and what datatypes do I need to use?
Resources (For my files)
file_id
filename (Files are presorted and display names and paths are derived
from here.)
file_type (PDF | AUDIO | VIDEO | PHOTO [Also used to generate file
urls])
upload date (timestamp in PHP or MySQL)
uploaded_by (User ID from Users table)
event (event_id from Events table, optional)
Users (User accounts - for admin access and maybe a notification list)
user_id
first_name
last_name
email
password
phone_number (optional)
permissions_level (read only, upload)
creation_date
Events
event_id
event_name
event_location
event_date
event_description
entry_date
What I would take:
Resources (For my files)
file_id INT (or SMALLINT depending on the number of expected entries)
filename VARCHAR (or text if longer than 255 chars)
file_type ENUM (if only those you mentioned or VARCHAR if dynamic types can be added)
upload DATE DATETIME (or DATE if you don't need the time)
uploaded_by INT (or SMALLINT but the same as in the user table)
event INT (or SMALLINT but the same as in the event table)
Users (User accounts - for admin access and maybe a notification list)
user_id INT (or SMALLINT depending on the number of expected entries)
first_name VARCHAR
last_name VARCHAR
email VARCHAR
password CHAR(40) (for a SHA1 hash)
phone_number VARCHAR (as it might contain something like -, / or +)
permissions_level TINYINT (if only number values and at most 127 values)
creation_DATE DATETIME (or DATE if you don't need the time)
Events
event_id INT (or SMALLINT depending on the number of expected entries)
event_name VARCHAR
event_location VARCHAR
event_DATE DATETIME (or DATE if you don't need the time)
event_description TEXT (as 255 of VARCHAR might be to short)
entry_DATE DATETIME (or DATE if you don't need the time)
When you have set up your database and input some dummy data, you can run a simple statement through phpmyadmin that will tell you, what MySQL would take for that exact dummy data:
SELECT * FROM events PROCEDURE ANALYSE()
In the column Optimal_fieldtype you will find what MySQL tells you to take. But you should not take that exact fieldtype. It will tell you very often to take a ENUM but most of the time you add random data so you have to take a VARCHAR in that cases the column Max_length will give you a hint on how long it should be. But on all VARCHAR fields you should add additonal space depending on how long you expect the values to be. Take in consideration that even a name can be longer than 50 chars.
Your user table doesnt have a column for the password hash. Not sure if you intended for it to have such or not. I cant see how we can answer what datatypes should be used, since it completely depends on how you plan on using the columns. For dates, I prefer datetimes over timestamps, but thats just a personal preference as I like to manually insert the dates in the queries.
What is missing, well that is sort of for you to decide / what is required. You should read up on Designing databases.
As far as the datatypes for what you have
The id fields should be a INT, or BIGINT (depends on how big your application may become) and set as the PRIMARY KEY.
The names should be a varchar how long you want it depends on what your requirements are. Most first / list names are generally 25-30 characters max. Event names could be upwards to 250, depending on your requirements.
The location will be similar to the name as a VARCHAR somewhere around 50-150, depending on your requirements.
The date should be a DATETIME field.
The description should be either a VARCHAR(250) or a TEXT field.
The permissions really depends on how you want to handle it. This could be an INT or a VARCHAR (incase you want to serialize an array).
Phone number could be an INT (if you want to strip all non-numeric characters and format it your own way) or a VARCHAR(15) if you do not want to strip the characters
EMail should be a VARCHAR(250).
Hopefully this helps, again it really depends on your requirements for the application and what you have envisioned. But the initial types can always be changed as your requirements change.
EDIT
And if you want to know full information about the different MySQL Data Types, read the manual: http://dev.mysql.com/doc/refman/5.0/en/data-types.html

Categories