PHP mysql bigint issue - php

I have two tables with bigint:
table1
id bigint(20) PK autoincrement
name varchar(40),
text
table2
id bigint(20) PK autoincrement
created datetime
text_field
id_table1_ref bigint(20)
After inserting data into table1 and trying to insert table1.id into table2.id_table1_ref,
the number is different, i.e.:
Number 1552545662588 from table1.t1 becomes 1552545662, or even worse, a negative number.
I know this is an issue with settings, but I can't figure out how to manage this.
I tried to set up signed/unasigned values for the fields, but it doesn't work.
This is happening on my UNIX local computer, on the server all is working ok, at least for now.
Any help would be much appreciated.

You need to CONVERT it to a string in SQL before getting it into PHP. In PHP, you can use GMP to handle the number.
MySQL docs on converting: http://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert

It's also the case that PHP under at least some 64-bit operating systems (eg FreeBSD AMD64) uses an 8-byte int, verifiable by testing with
echo 'Size of int is '.PHP_INT_SIZE ;
So if you're only going to be running a 64-bit operating system, you shouldn't need to manage the BIGINTs as strings in PHP.

I solved this problem by change to another php version,that is changing from 64bit php version to 32bit php version. That really works for me.

Related

Mysql Error 1071 Specified Key value is too Long

I'm using my Web Application in Godaddy Hosting Server. Php Version is 7.1 and mysql Version is 5.6
while i'm trying
ALTER TABLE aos_products_quotes
modify COLUMN discount varchar(255) DEFAULT 'Percentage' NULL ,
modify COLUMN parent_type varchar(255) NULL ,
modify COLUMN parent_id char(255) NULL ;
these query in my domain sql server its shows
MYSQL #1071 Error Specified Key value is too long
I think i need to use mysql 5.7 or else need to set the global prefix variable is 1..But the Global setting need super privileges..At Godaddy side they told its impossible on Shared hosting..
I try my best about that issue so anyone guide me to solve that issue..
Thanks in advance...
There are many options to fix this:
You can try by changing the character set of columns so that they
use less bytes in storage.
You can change / remove indexing of the table. May be you are using
composite index whose limit is reached after this alteration.
Try less length of varchar() columns.
share the complete table structure to help you better.
Thanks

How to prevent two user get same unique key?

I am creating a system to generate unique keys. It works for now. But, I haven't tested it with many users. Users may click a button and then get his unique number, as simple as that.
But, How to prevent multiple users getting the same unique keys,if they press the button exactly in the same time (even in ms scale)? The button is on client side, so I must do something in the back end.
This is the unique key looks like:
19/XXXXXX-ABC/XYZ
The XXXXXX is auto increment number from 000001 to 999999. I have this code but didn't know if it's reliable enough to handle my issue.
$autoinc = $this->MPenomoran->get_surat($f_nomor)->jumlah_no+1; //count data in table and added 1
$no_1 = date('y')+2;
$no_2 = str_pad($autoinc, 6, '0', STR_PAD_LEFT);
$no_3 = "-ABC/XYZ";
$nomor = $no_1."/".$no_2.$no_3;
$returned_nomor = $nomor;
$success = array ('nomor' => $returned_nomor); //sent unique keys to user's view
It seems like you don't want to come out and tell us what the platform is for this, or what the limitations to that platform are.
The first thing that jumps out is that your format is limited by year, to 999999 total unique keys. Very odd, but presumably you understand that limit, and would need to put in some code to deal with hitting the maximum number.
Approaches
REDIS based
This would be very simple with a REDIS server using the INCR. Since INCR is atomic, you essentially have a solution just by creating a key named for your year + 2, should it not exist, and using INCR on it from there on out.
You would need to utilize some php redis client, and there are a variety of them with strengths and weaknesses to each that I'm not going to go into.
Redis is also great for caching, so if at all possible that is the first thing I would look into.
MySQL Based
There are a few different solutions using mysql. They are involved, so I'll just outline them because I don't want to spend time writing a novel.
Note: You will need to translate these into the appropriate PHP code (mysqli or PDO) where as noted, parameters are passed, transactions started etc.
MySQL - create your own sequence generator
Create a table named "Sequence" with this basic structure:
name varchar(2) PK
nextval unsigned int default 1
engine=InnoDB
The underlying query would be something like this:
BEGIN_TRANS;
SELECT nextval FROM Sequence WHERE name = '$no_1' FOR UPDATE;
UPDATE Sequence SET nextval = nextval + 1;
END_TRANS;
This code emulates a serialized Oracle style sequence. It is safe from a concurrency standpoint, because MySQL will lock the row briefly, then increment it upon completion.
MySQL - Autoincrement on multi-value PK
This comes with some caveats.
It is generally incompatible with replication.
The underlying table must be myisam
name varchar(2) PK
lastval unsigned int AUTO_INCREMENT PK
engine=MyISAM
Your underlying query would be:
INSERT INTO Sequence (name) VALUES ('$no_1')
This depends on mysql supporting a multi-column key where the 2nd column is an AUTO_INCREMENT. It's behavior is such that it acts like a sequence for each unique name.
You would then use the relevant api's built-in approach to getting the mysql LAST_INSERT_ID(). For example with PDO
Other alternatives
You could also use semaphores, files with locking, and all sorts of other ideas to create a sequence generator that would work well in a monolithic (one server for everything) environment. MySQL and Redis would serve a cluster, so those are more robust options from that standpoint.
The important thing is that whatever you do, you test it out using a load tester like siege or Boom to generate multiple requests at your web level.

Bigint issue when will be displayed at template

I have a MySQL database with a bigint field but when I'm using on cakephp the number 697483533702444 is being displayed as 2147483647
You need to either use a 64bit version of PHP or store your data in the database as a CHAR(20) or VARCHAR(20)
I cant write comment (missing points), but I experienced some Problems with signed and unsigned Integers and quite similar results. Please try changing signed and unsigned in the database.

Why does Doctrine generate different constraint names?

I am using Symfony2 with Doctrine to generate my MySQL tables. Usually, Doctrine is able to update the database quite easily.
The MySQL server is on a linux machine. There is also an Apache running which hosts my Symfony application. When running php app/console doctrine:schema:update --dump-sql on the Linux machine Doctrine tells me that my database is up to date.
However, when running this command on Windows on the exact same Symfony application and connecting to the MySQL server on the Windows machine, Doctrine wants to change quite a few of the constraint names. It seems that it wants to rename all the indices:
DROP INDEX idx_2d91b64f56629d6d ON table1;
CREATE INDEX IDX_13241BA356629D6D ON table1 (col1_id);
DROP INDEX idx_2d91b64fbad26311 ON table1;
CREATE INDEX IDX_13241BA3BAD26311 ON table1 (col2_id);
DROP INDEX idx_bc100bf27dc308 ON table2;
CREATE INDEX IDX_8C245317DC308 ON table2 (col3_id);
// some more similar lines omitted
Why does this happen? I had a look at how Symfony generates the constraint names and it is using dechex and crc32, both of which should be platform-independent.
This may not be the cause, but it does look like a possible cause:
http://php.net/manual/en/function.crc32.php
In the red section, it states that crc32 can return negative or positive values depending on 32 or 64 bit systems.
This is because of the range of a 32 signed integer: −2,147,483,648 to 2,147,483,647.
If you take from this that crc32 assumes to work with unsigned bytes, any value it produces over 2,147,483,647 will become negative.
Then dechex will produce a hexadecimal value based on the decimal value, negative or possible.

How to handle Facebooks new UID sizes?

I've been working a little bit on a Facebook application, but when I registered a new user to test the friend interaction the new user got a uid (100000XXXXXXXXX) that seems to big for php to handle.
Saving the number in the database results in the same value (2147483647). I'm guessing this is also PHPs fault, as I would believe the uid would fit in an unsigned bigint?
I'm not quite sure where to go from here, any suggestions?
The fix is to store the UID as a string always. Use the VARCHAR field type in MySQL and you will be fine.
In general, many database gurus will tell you that interpreting another application's foreign keys (like UID in this case) is bad bad bad and you should handle them as opaque text.
Facebook recommonds to store it as a BIGINT unsigned.
User object details and connections can be found here.
For PHP, you'd store it as a string (because, ultimately, if you're going to use it, it's going to be displayed on the page or in JSON data or something else that's stringy. There's no real need to perform arithmetic on that number).
I'm using BIGINT UNSIGNED for a couple applications and it works just fine.
What type of MySQL field are you storing the UID data in? An unsigned bigint can store up to 18446744073709551615. (See http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html)
Simply update your schema via something like...
ALTER TABLE <table name> MODIFY COLUMN <column name> BIGINT UNSIGNED NOT NULL;
...and I suspect all will be well.
NB: You'll want to try this on a backup to ensure I'm not deeply incorrect. :-)

Categories