I have a database for an online game, and i need to store total score of user playing game. Each time user end a match, his score will be automatically updated.
I'm trying to keep this score as VARCHAR, then retrieve it from a script, parse to int, add last score, parse again to string, and update database. But as i can see, php is not able to manage big numbers. How can i do?
MySQL has BIGINT type. PHP itself works flawlessly with BIGINT.
Unless you want numbers way bigger than that, I have no idea why would you use anything else.
Note: unsigned BIGINT is twice as big as BIGINT
unsigned BIGINT can store numbers up to: 18,446,744,073,709,551,615
signed BIGINT can store numbers up to: 9,223,372,036,854,775,807 (or with 8 at the end on the negative side)
So basically, You can store numbers up to around 1,8*10^19. Need more? Then look at BC at the other answer here.
For comparison:
INT can store up to 2,147,483,647 or twice as much when unsigned, which means that BIGINT is roughly 4,294,967,295 times larger than INT. Yes. BIGINT is basically very close to INT^2
You need to use BC:
You can work with numbers as strings in PHP using BC, so they are arbitrary big, as you are already using in your database.
Best regards.
Related
I have question about the best solution to store number code
(example: 1234123412341234).
This code have always 16 chars and is numeric value!
I use InnoDB engine to store table
Currently i have type of column VarChar(16) but i have thoughts whether bigint is better for this.
Column code is not edited after added to database.
Bigint requires 8 Byte to store a number, while varchar(16) will require at minimum the double amount of Bytes. Depending on the character set used, even 4 times more. So type of bigint will save space on your disk but also reduce network traffic.
A varchar(16) will not be able to represent all bigint numbers. An unsigned bigint value of 0xFFFFFFFFFFFFFFFFFE can't be stored in a varchar(16) column.
On machine Level, a 16 Byte comparison usually happens in one cycle, while comparing strings is much more expensive, since varchar requires a byte to byte comparison.
You should choose the datatype based on the data you have.
For example a credit card number is a character string (even if it contains numbers), likewise a telephone number is a character string (as string can for example have leading zeros etc).
A number with numeric value should be stored as a number (a distance the to moon for example).
The key question to ask is what operations do you need to do on the data?
A numeric data type like BigInt can be used with operations like addition, subtraction, multiplication, division. Values will be normalised so that 1, 001, 1.0, etc will all be stored the same.
A string data type like VarChar can be used with operations like sub-string matches. It can store values like 0001 without normalising them.
It is very rare that one piece of data needs both those types of operations. For instance, you might want to look for all phone numbers beginning "1800", but would never need to divide a phone number by 3.
So when you say your data is a "number code", you need to think about whether this value is actually a number, or just a string which is all digits.
I want to show the following numbers with php, but output is strange:
echo 3333333333333333333333333333333; // -----------> 3.3333333333333E+30
echo 0.000025; // -----------> 2.5E-5
I havent asked it to convert. Why it does that? How should I force it to get/set the values exactly as I ask it? (p.s. I've heard of sprint_f or number_format functions, but I don't like them, because i have to know the formatting and length in advance.)
What is more, when I try to save large numbers in Database, there is saved a number: 2147483647 (i found that was the max. integer value). I changed the column type from int to varchar(100) but still same truncation happens.
Look at your precision setting in php.ini
http://php.net/manual/en/ini.core.php
It's the setting that says how PHP will output numbers
When you are using such extreme numbers (both negative or positive) the accuracy of the number system in php comes in to play.
Floating point is not accurate for numbers like that, I would suggest using one of the ones listed here
http://php.net/manual/en/refs.math.php
bc is designed for decimals
Well, I will answer my own topic.
1) The first problem is that PHP truncates LARGE and smallest values... However, I solved that casting values to strings (with double quotes).
2) The second problem was a bit strange...
When I first created that MySQL, I made that column as INT(11) and then changed column to Varchar(100) (exactly as all my other columns were Varchar(100) and they could save that value well).
However, that column was truncating values again. Then I recreated the table, but changed the COLUMN name and then IT WORKED WELL! I think, MySQL cached the column type (or surely something like that happened) !
I have to store an IP address into a MySQL table running on a 32 bit system.
On a 64 bit system I would simply use INT(10) UNSIGNED since ip2long will always be an absolute value.
How to make it work on 32 bit? I have two options.
Remove UNSIGNED and store negative values, but I'm not sure if
there is still a chance of values being too large or too small once
this is done (because the upper limit will be decreased by half to
allow for the lower limit to be negative)
Use sprintf("%u",ip2long( $ip )) checkout this post (will be probably slower than 1.)
Any other solutions?
You can try to convert IP not in PHP but in SQL insert query using INET_ATON function https://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton. You need to use INT UNSIGNED as your column type.
This question already has answers here:
MySQL PRIMARY KEYs: UUID / GUID vs BIGINT (timestamp+random)
(4 answers)
Closed 8 years ago.
I am developing a GPS device based application in Cakephp 2.0 and mysql (InnoDB). Each device sends data every minute to the Db and I need to make it scalable to a very large number of devices simultaneously to the server.
I have not used BIGINT auto increment as primary key because there is a limit and max value beyond which the limit to BIGINT will be reached and the system will fall apart, even if far away.
I created the primary key as char(36) and generated UUID from php and started storing the data. Primarily because the limit and uniqueness of the primary key will never stop and the design will never fail.
Uniqueness is the only reason for me and nothing else.
Problems:
The system is in pilot testing mode and time to insert the data has increased to very large extent. Refer to http://kccoder.com/mysql/uuid-vs-int-insert-performance/ This is exactly happening in my case where by time, the time to insert the data is increasing and i expect that it might get worse in the coming days as the number of data keeps increasing. There are around 2,00,000 data in the table now.\
The primary key being char(36), i assume the performance is getting effected in inserts, select statements and joins.
My idea is to replace the primary key UUID column with a varchar(50) column and have Device ID / IMEI Number + timestamp stored as primary key and they will always be unique. But on the downside, it's again a varchar field and performance issues on long run.
What is the best option for me in the long run?
Just use BIGINT UNSIGNED.
An unsigned INT64 is something like 4.000.000.000 times 4.000.000.000. So assuming you have one device for each of the less than 8 billion people on the planet logging once per second, that leaves you with 2 billion seconds or more than 63 years. I assume, that in 63 years an INT128 is normal (or small).
I am also quite sure, that you will run into very different classes of trouble long before you reach 2^64 rows in a single table.
So, I've created a datatable that asks for a users Mobile Provider (varchar), phonenumber, and pin. The table seems to work well except that when a user inputs a phone number the original number converts to 2147483647. I've spent sometime looking around and I learned that this is because I've gone beyond the 32-bit limit on my table. In order to fix this, I need to make my integer limit larger than 10 (what I originally had) in MYSQL database.
I've changed the MYSQL table using PhpMyAdmin; however, I am still getting the same problem. Is this because I need to now change something on the Yii-end?
I know that I could use CRUD to contstruct a new MVC relationship - but I've already added in quite a few functions to the Model and the Controller. Is there a way with Yii to change my database in piecemeal way? I.e. without having to use Crud?
The fact that telephone directory numbers (DNs) resemble integers notwithstanding, using a integer of any width to store a DN is very bad practice indeed.
That's because, as you have discovered, DNs that get manipulated as if they were integers sometimes become corrupted.
Using a 32-bit number to store a North American Dialing Plan number (Canada, Caribbean, US) is just flat incorrect. Partway through the 429 area code, your numbers will be corrupted even if you manage to use an unsigned integer.
Use varchar(20) and you'll be fine.
Here's something to think about: ITU-T recommendation E.123 for representing telephone numbers. http://en.wikipedia.org/wiki/E.123
INT is still a 32-bit number, the (10) in INT(10) is an artificial cap that's mostly useful for saying how far ZEROFILL should fill to.
Try BIGINT(10), as this will allow all 10-digit numbers, even those higher than 231-1