Storing Database MAC Addresses
There are three options for storing a MAC address in a database column:
- CHAR(12) - takes up a great deal of space and is inappropriate for indexes or unique keys.
- BIGINT - requires converting between hexadecimal and decimal every time you store or query data.
- Supporting Table ID - with a secondary CHAR(12) column. It requires a join for all queries, and may still require a BIGINT ID column depending on the number of different MAC addresses expected. Also any uniqueness constraint also runs up against the problems listed for CHAR(12).
The mysql database I created last year was over a billion rows per month and had a unique key and index on the MAC address column, so I immediately had to reject the CHAR(12) and likely the supporting table option. But the developers interacting with the database had varying levels of familiarity with sql and... uh... basic math, so the BIGINT was problematic. My solution was to create a pair of functions to do the conversion as painlessly as possible.
CREATE FUNCTION INTADDRESS (hexaddress CHAR(12)) RETURNS BIGINT UNSIGNED NO SQL
BEGIN
RETURN CONV(hexaddress,16,10);
END;
CREATE FUNCTION HEXADDRESS (intaddress BIGINT UNSIGNED) RETURNS CHAR(12) NO SQL
BEGIN
RETURN LPAD(HEX(intaddress),12,"0");
END;
All incoming MAC address strings are sent through "INTADDRESS," while all outgoing sql use "HEXADDRESS," as shown in the following examples:
INSERT INTO device_usage (mac,upload,download) VALUES(INTADDRESS('ABCDEF012456'),100,100);
SELECT SUM(upload),SUM(download) FROM device_usage WHERE mac=INTADDRESS('ABCDEF012456');
SELECT HEXADDRESS(mac),SUM(upload),SUM(download) FROM device_usage GROUP BY mac
The important thing to remember with this setup, is that "HEXADDRESS" is only for formatting the returning SQL results. In WHERE clauses, you always want to run the "INTADDRESS" function on the static side of the data being compared (the MAC address you are trying to match) rather than the database table side (which would run the function on every single row and thereby not utilize any of the relevant table indexes).


![[bluehost]](http://mleiv.com/wp-content/files/site_images/bluehost.gif)
Hi
just extend the INTADDRESS Function as follows
CREATE FUNCTION INTADDRESS (hexaddress CHAR(17)) RETURNS BIGINT UNSIGNED NO SQL
BEGIN
SET hexaddress = REPLACE(hexaddress,':','');
SET hexaddress = REPLACE(hexaddress,'.','');
SET hexaddress = REPLACE(hexaddress,'-','');
RETURN CONV(hexaddress,16,10);
END;
So you can give the function the mac in
the usual formats.
Cheers Patrick
In my case, it was easier to do the filtering in PHP because of its more developed regex, but given that direct sql is used by others, yes, it would be a good idea to at least approximate the filtering in the stored procedures as well.