diff --git a/storage/sql/config.go b/storage/sql/config.go
index f3dede4a1571594c3962a6b23cc7c2e41fea9449..170dfd0001a23ab5b15f94c8b96f9af8488c86bb 100644
--- a/storage/sql/config.go
+++ b/storage/sql/config.go
@@ -66,7 +66,7 @@ func (s *SQLite3) open(logger log.Logger) (*conn, error) {
 		return sqlErr.ExtendedCode == sqlite3.ErrConstraintPrimaryKey
 	}
 
-	c := &conn{db, flavorSQLite3, logger, errCheck}
+	c := &conn{db, &flavorSQLite3, logger, errCheck}
 	if _, err := c.migrate(); err != nil {
 		return nil, fmt.Errorf("failed to perform migrations: %v", err)
 	}
@@ -239,7 +239,7 @@ func (p *Postgres) open(logger log.Logger) (*conn, error) {
 		return sqlErr.Code == pgErrUniqueViolation
 	}
 
-	c := &conn{db, flavorPostgres, logger, errCheck}
+	c := &conn{db, &flavorPostgres, logger, errCheck}
 	if _, err := c.migrate(); err != nil {
 		return nil, fmt.Errorf("failed to perform migrations: %v", err)
 	}
@@ -344,7 +344,7 @@ func (s *MySQL) open(logger log.Logger) (*conn, error) {
 			sqlErr.Number == mysqlErrDupEntryWithKeyName
 	}
 
-	c := &conn{db, flavorMySQL, logger, errCheck}
+	c := &conn{db, &flavorMySQL, logger, errCheck}
 	if _, err := c.migrate(); err != nil {
 		return nil, fmt.Errorf("failed to perform migrations: %v", err)
 	}
diff --git a/storage/sql/migrate.go b/storage/sql/migrate.go
index 5b86bc78d8f61fe6755c93cf4b36b23beb8df65f..5e42d05f9bada17e272f27473615fbc737b996d7 100644
--- a/storage/sql/migrate.go
+++ b/storage/sql/migrate.go
@@ -18,6 +18,14 @@ func (c *conn) migrate() (int, error) {
 
 	i := 0
 	done := false
+
+	var flavorMigrations []migration
+	for _, m := range migrations {
+		if m.flavor == nil || m.flavor == c.flavor {
+			flavorMigrations = append(flavorMigrations, m)
+		}
+	}
+
 	for {
 		err := c.ExecTx(func(tx *trans) error {
 			// Within a transaction, perform a single migration.
@@ -31,13 +39,13 @@ func (c *conn) migrate() (int, error) {
 			if num.Valid {
 				n = int(num.Int64)
 			}
-			if n >= len(migrations) {
+			if n >= len(flavorMigrations) {
 				done = true
 				return nil
 			}
 
 			migrationNum := n + 1
-			m := migrations[n]
+			m := flavorMigrations[n]
 			for i := range m.stmts {
 				if _, err := tx.Exec(m.stmts[i]); err != nil {
 					return fmt.Errorf("migration %d statement %d failed: %v", migrationNum, i+1, err)
@@ -64,7 +72,11 @@ func (c *conn) migrate() (int, error) {
 
 type migration struct {
 	stmts []string
-	// TODO(ericchiang): consider adding additional fields like "forDrivers"
+
+	// If flavor is nil the migration will take place for all database backend flavors.
+	// If specified, only for that corresponding flavor, in that case stmts can be written
+	// in the specific SQL dialect.
+	flavor *flavor
 }
 
 // All SQL flavors share migration strategies.
diff --git a/storage/sql/migrate_test.go b/storage/sql/migrate_test.go
index e94e819f0c2ef034babbf68ec040c0c74f444d5e..a528aa7e627099932b7eadc12d85d24f3154d039 100644
--- a/storage/sql/migrate_test.go
+++ b/storage/sql/migrate_test.go
@@ -30,8 +30,15 @@ func TestMigrate(t *testing.T) {
 		return sqlErr.ExtendedCode == sqlite3.ErrConstraintUnique
 	}
 
-	c := &conn{db, flavorSQLite3, logger, errCheck}
-	for _, want := range []int{len(migrations), 0} {
+	var sqliteMigrations []migration
+	for _, m := range migrations {
+		if m.flavor == nil || m.flavor == &flavorSQLite3 {
+			sqliteMigrations = append(sqliteMigrations, m)
+		}
+	}
+
+	c := &conn{db, &flavorSQLite3, logger, errCheck}
+	for _, want := range []int{len(sqliteMigrations), 0} {
 		got, err := c.migrate()
 		if err != nil {
 			t.Fatal(err)
diff --git a/storage/sql/sql.go b/storage/sql/sql.go
index 45ecdd797b6cba8bf09751b51108be317a94dae8..4f1ed6c9cf0ee1e5b0eef564f530f7a894e89cd2 100644
--- a/storage/sql/sql.go
+++ b/storage/sql/sql.go
@@ -130,7 +130,7 @@ func (c *conn) translateArgs(args []interface{}) []interface{} {
 // conn is the main database connection.
 type conn struct {
 	db                 *sql.DB
-	flavor             flavor
+	flavor             *flavor
 	logger             log.Logger
 	alreadyExistsCheck func(err error) bool
 }