How to mark the default row to select in a many to many relationship
A UNIQUE constraint on (product_id, default) won't work since you can have several images that are not default for each product. A similar approach is to add a display_order attribute:

CREATE TABLE product_images
( product_id ... NOT NULL
      references ...
, image_id ... NOT NULL
      references ...
, display_order SMALLINT NOT NULL
,     PRIMARY KEY (product_id, display_order) )


To get the default image for a product choose the one with the smallest display_order for that product.

Depending on your business requirements you may add an alternative key. Examples:

-- An image may not be reused between products
ALTER TABLE product_images ADD CONSTRAINT ...
    UNIQUE (image_id)

-- An image may not be used several times for each product
ALTER TABLE product_images ADD CONSTRAINT ...
    UNIQUE (image_id, product_id)


To get the default image for a product:

SELECT image_id
FROM product_images
WHERE product_id = ?
ORDER BY display_order
LIMIT 1;


EDIT: I keep forgetting this bug in MySQL ...

To assign a new default image for a product:

UPDATE product_images x     
    SET display_order = (SELECT min from (SELECT MIN(display_order)-1 as min                                        FROM product_images                          
                                          WHERE product_id = ?) as y)
WHERE product_id = ?   
  AND image_id = ?;


or possibly:

UPDATE product_images x     
    SET display_order = (SELECT min 
                         FROM (
                             SELECT display_order-1 as min                         
                             FROM product_images                          
                             WHERE product_id = ? 
                             ORDER BY display_order LIMIT 1
                         ) as y
                        ) 
WHERE product_id = ?
  AND image_id = ?;