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
Related
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'm currently scraping virtual currency transaction data off a webpage. The transactions consist of time/date, a description, price, and new balance.
Results are paginated. I can fetch 20 at a time. My goal is to have an accurate record of all entries in a separate database. There are a very large number of transactions occurring, and transactions can occur at any time, including between fetching different pages.
Time/date is measured to the minute, so multiple transactions can occur in the same minute. Descriptions can also be the same (for example the same item can be sold in the same quantity to the same person multiple times). Both price and balance could also overlap.
I am storing a timestamp, price, balance, and data which is parsed from the description in multiple fields. I need to be able to tell if an entry is already in the database quickly. The maximum effect I could get is to ensure that each entry has a unique time/data, description, price, and balance. The issue with composite keys is that I don't want to store the full description in the database. (This would double the database size.)
My solution that I came up with was to create a BIGINT hash based on those fields, which would be used as a UNIQUE field in the database. I found that the probability of a collision (based on the birthday attack formula) would be less than 1% for up to 61 million entries, which is a satisfactory probability, since the number of entries I'm planning to track is in the neighbourhood of 40k-2m.
My question is, based on my application and goals, which hashing algorithm would you recommend and how can I get the values from it in to a BIGINT size without losing any of the properties of the algorithm? The most important thing is to avoid collisions, as each one would affect the integrity of the data. Unless you have a better idea, my plan was to concatenate the data into a string (with separators between fields) then feed it into the function. Short code snippets are much appreciated!
Because I don't care about security, I used SHA1. This generates a 20-byte hexadecimal string. BIGINT is 8 bytes in size. Therefore, we need to truncate to 16 characters (since each character is half a byte in hex) using substr, and use base_convert to convert to base 10 for database storage.
function hashToBigInt ($string) {
return base_convert(substr(sha1($string), 0, 16), 16, 10);
}
Thanks everyone for all your help!
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.
I have some phone numbers (validated such that all containing only integers, no - or + in them) as strings in a text file.
I am doing a simple mysql update on a mysql table which has phone number column as int(12). Note that I convert each phone number extracted from the text file to integer using intval().
The problem that I am facing is that instead of the numbers being inserted I just get 2147483647 to be inserted in each column. I guess I am making a small silly mistake somewhere, but still I can't figure it out. Can anyone explain what mistake am I making?
EDIT: Here is my the piece of code I am using (It does not give any sql error):
$sql="UPDATE ".$table." SET mobile = ".intval($smob).", phone = ".intval($sphone)." WHERE roll='".$sroll."'";
mysql_query($sql, $con) or die(mysql_error());
Excerpt from intval() manual:
The maximum value depends on the system. 32 bit systems have a maximum signed integer range of -2147483648 to 2147483647. So for example on such a system, intval('1000000000000') will return 2147483647. The maximum signed integer value for 64 bit systems is 9223372036854775807.
What you are getting is a maximum number for signed integer on a 32bit machine.
I would strongly advise you to not use this function for phone number conversions. One of the simple reasons is that my mobile number is 11 digit number (without leading + or double zero for international access), and I believe there are some countries that have even more digits.
Why you would need to store phone numbers as int's? Since most likely you are not doing some calculations and statistics on who might have a biggest phone number among your clients, and this data is probably used only for invoicing or a contact info, you could just leave that as a string.
Phone numbers are not integers, and should not be stored using an integer type.
The observed behaviour happens because the values you are trying to store are outside the range accepted by the column type. I recommend putting MySQL into strict mode - this forces it to return errors when inserted data, etc. cannot be stored, instead of silently trying to do whatever is the least bad thing without failing.
I hope I can explain this good enough. I have 3 tables. wo_parts, workorders and part2vendor. I am trying to get the cost price of all parts sold in a month. I have this script.
$scoreCostQuery = "SELECT SUM(part2vendor.cost*wo_parts.qty) as total_score
FROM part2vendor
INNER JOIN wo_parts
ON (wo_parts.pn=part2vendor.pn)
WHERE workorder=$workorder";
What I am trying to do is each part is in wo_parts (under partnumber [pn]). The cost of that item is in part2vendor (under part number[pn]). I need each part price in part2vendor to be multiplied by the quantity sold in wo_parts. The way all 3 tie up is workorders.ident=wo_parts.workorder and part2vendor.pn=wo_parts.pn. I hope someone can assist. The above script does not give me the same total as when added by calculator.
This is not an answer, just a comment.
Why don't you take the sum/multiply operation outside the SQL statement? I know, that seems stupid because it will increase the lines of code and the complexity of the script, but, imho, it is always a good thing to keep code and SQL statements as far away as possible.
The key cause I could see for something like this would be a type issue. For example, this could happen if you are using FLOATs instead of NUMERICs, you might get a slightly different answer. That is a mistake that is way too common, btw.
I would recommend double checking your schema to make sure you are using NUMERICs across the board here. NUMERIC is crazy-powerful on PostgreSQL, it performs very well, and it properly supports arbitrary precision operations. If you can't change the data type, cast your fields to numeric in your query.
FLOAT types (including DOUBLE) are fixed precision binary numbers, and they don't correspond exactly to base 10 numbers always. NUMERICs are stored internally as base 1000 (meaning 9 digits per 30 bits), and this is very efficient to convert to/from binary. The precision is also arbitrary, although it does have a maximum. However, for financial stuff, the maximum values or precision are not an issue with numeric data types. You should use them liberally.