20200906のMySQLに関する記事は5件です。

mac環境でrailsを起動する(mysql)

今回はrailsを用いたポートフォリオ作成の為に今までcloud9で開発していたのをローカル環境で行う。その備忘とアウトプットです。
今後も掲載していくので何か気付きがありましたら報告よろしくお願いします!:bow_tone1:

rails ruby などなどはすでにインストールを以前済ませた為mysqlの起動から

mysqldのターミナル上での起動
mysql.server start

mysqldのターミナル上での起動ステータスの確認
mysql.server status

mysqlが起動していなかった場合
ERROR! MySQL is not running

mysqlが起動していた場合
Starting MySQL
.. SUCCESS!

となるmysqlが起動されステータスokであれば
rails sでrailsサーバーを起動するtと以下のログが時発生するので

image.png
https://gyazo.com/35a5d81be14535389ca6fce42a2b62e3

最終行の://localhost:3000をコピーしhttp://localhost:3000
ネットワークで検索をかける

827992458a77dd1af90c00ee8da3ddc4.jpg

見覚えのあるこちらの画面が出ればローカル環境でのrails起動が完了する。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【学習メモ】テーブル作成における制約のかけ方 ※引用多め

色々な制約方法

  • NOT NULL制約
  • DEFAULT制約
  • PRIMARY KEY制約
  • UNIQUE制約
  • AUTO_INCREMENT

※本当は外部キー制約などもっとありますが、またの機会に。

NOT NULL制約

テーブルを作成するときにカラムに対して NOT NULL 制約を付けることが可能。書式は次の通り。

CREATE TABLE db_name.tbl_name
  (col_name data_type [NOT NULL | NULL], ...)

例:

create table friends(
  name varchar(10) not null,
  address varchar(10)
  );

補足:作成したテーブルのカラム情報の確認方法

show columns from tbl_name;

DEFAULT制約(カラムにデフォルト値を設定する)

カラムに DEFAULT 制約をつけることでカラムにデフォルトの値を設定できる。データを追加したとき、対象のカラムに値を指定しなかった場合にはデフォルト値がカラムに格納される。MySQL における DEFAULT 制約の使い方について解説。

CREATE TABLE db_name.tbl_name
  (col_name data_type [DEFAULT {literal | (expr)}], ...)

例:

CREATE TABLE hoge
  (
    num1 int default 10,
    str1 varchar(10) default 'Hello',
    num2 float default (rand() + 3.2),
    d date default (CURRENT_DATE)
  );

カラムのデータ型のあとに DEFAULT 定数 と記述することでカラムにデフォルトの値を設定できます。テーブルにデータを追加するとき、すべてのカラムに値を指定する必要はありませんが、デフォルト値が設定されているカラムに値が指定されなかった時にデフォルト値に設定された定数が格納されます。

以前のバージョンではデフォルト値に定数以外で指定できるのは NOW() 、 CURRENT_DATE() 、 CURRENT_TIMESTAMP() の3つだけでしたが、 MySQL 8.0.13 以降では定数の他に組み込み関数や演算子を指定することができます。定数以外を指定する場合は括弧()で囲むことで値と区別します。

PRIMARY KEY制約(主キー/プライマリキーを設定する)

プライマリーキー(主キー)とは作成したテーブルの中の1つまたは複数のカラムの組み合わせに対して設定するもので、テーブルに格納されているデータに格納されているデータを識別するための目印のようなものです。ここではプライマリキーについての簡単な解説と、MySQLのテーブルでプライマリキーを設定して利用する方法について解説します。

プライマリーキー(主キー)とは

テーブルには多くのデータが含まれており、 1 つ 1 つのデータには複数のカラムの値が格納されています。格納されたすべてのデータの中から 1 つのデータを特定したいときに、 1 つまたは複数のカラムの値を検索してデータを特定しますが、その時に最も適したカラムに設定されるのがプライマリーキーです。

カラムにプライマリーキー制約を設定すると、カラムには他のデータの値を重複することのない値しか格納することができなくなります。また NULL も格納することができません。その結果、プライマリーキー制約が設定されたカラムの値を検索することで、テーブルの中でただ一つのデータを特定することができます。

プライマリーキーが設定されたカラムに対しては自動的にインデックスが作成されます。インデックスとは指定したカラムのデータを取り出して検索用にまとめたもので、インデックスを作成しておくとテーブルのデータを高速に検索できます。インデックスはテーブルの中で複数作成することができますが、その中でも重複する値が格納されておらず特に重要なカラムに対してプライマリーキーが設定されます。

プライマリーキーと似た制約にユニーク制約というものがあります。ユニーク制約が設定されたカラムも重複した値を格納することができませんが、 NULL を格納することができ、またテーブルに複数作成できるという点が異なります。

PRIMARY KEY制約の使い方

CREATE TABLE db_name.tbl_name
  (col_name data_type NOT NULL PRIMARY KEY, ...)

または

CREATE TABLE db_name.tbl_name
  (col_name data_type NOT NULL, ..., PRIMARY KEY(col_name, ...))

カラムのデータ型のあとに PRIMARY KEY を記述します。 PRIMARY KEY はテーブルごとに 1 つしか設定することができず、また設定するカラムには NOT NULL 制約を合わせて設定する必要があります。明示的に NOT NULL 制約を設定しなくてもエラーとはなりませんが、自動的に NOT NULL 制約が設定されます。

補足:インデックスって?

業務でデータベースの操作をする場合、データが大量に登録されているテーブルへアクセスする場合に索引(INDEX)を作成すると、SQLクエリの実行が劇的に早くなることがある。

索引(INDEX)を作成した方が良いケース

  • 項目数/データ数が多い大規模な表の1%~15%程の行を頻繁にアクセスする場合
  • WHERE句で頻繁に使用されている列である場合
  • 列の値が比較的一意である場合
  • 参照整合性制約で使用されている外部キーになっている列である場合 ### 索引(INDEX)を作成しない方が良いケース
  • データ登録件数が少ない表である場合
  • 列内の値がほぼユニークである場合
  • NULL値が多く、NULL以外の値を検索しない場合 ### 索引(INDEX)のメリット
  • 表検索(SELCET)する際、特定の行を素早く検索する事が出来る為、検索のパフォーマンスが早くなる
  • ソート作業を省略可能 ### 索引(INDEX)のデメリット
  • データの登録(INSERT)、変更(UPDATE)の際、索引変更のためのオーバーヘッドが加わるため、索引(INDEX)がないテーブルに比べると時間が掛かる
  • 索引(INDEX)を作成する領域が必要

UNIQUE制約(ユニーク制約を設定する)

重複した値の格納を防ぐ

CREATE TABLE db_name.tbl_name
  (col_name data_type UNIQUE, ...)
CREATE TABLE db_name.tbl_name
  (col_name data_type, ..., UNIQUE [index_name] (col_name, ...))

UNIQUE 制約が設定されたカラムには重複した値を格納できなくなります。この点は PRIMARY KEY 制約と似ていますが、 UNIQUE 制約の場合は値として NULL を格納することができ、また複数のカラムに NULL を格納できます。また複数のカラムに対して UNIQUE 制約を設定することができます。

例:

create table staff(
  id int unique,
  name varchar(10)
  );

※注意

UNIQUE 制約が設定された id カラムには自動でインデックスが作成されており、Key カラムの値に UNI と設定されています。

(id カラムの値が NULL 以外の既存のデータの値と同じデータを追加されると)Duplicate entry '値' for key 'インデックス名' というエラーが発生しました。 id カラムには UNIQUE 制約が付いていますので、既存の値と同じ値を格納しようとするとエラーになります。

複数のカラムの組み合わせに対してUNIQUE制約を設定する

UNIQUE 制約の対象となるカラムは 1 つだけではなく 複数のカラムの組み合わせに対して設定することができます。例えば 2 つのカラムの組み合わせに対して設定した場合、 2 つのカラムに格納されている値の組み合わせが他のデータと重複することはできなくなります。

1つまたは複数のカラムを対象とした UNIQUE 制約を設定するには次の書式を使用します。

CREATE TABLE db_name.tbl_name(
  col_name1 data_type,
  col_name2 data_type,
  ...,
  UNIQUE [index_name] (col_name1, col_name2, ...)
  )

UNIQUE 制約を設定すると自動でインデックスが作成されます。インデックス名( index_name )は省略可能です。省略した場合は対象となるカラム名などから自動的にインデックス名が付けられます。

例:

create table staff(
  joiny int,
  id int,
  name varchar(10),
  unique joiny_id_index (joiny, id));

UNIQUE 制約が設定された joiny カラムと id カラムには自動でインデックスが作成されており、 joiny カラムの Key カラムの値に MUL と設定されています。今回は複数のカラムの組み合わせに対して UNIQUE 制約を設定していますが、最初のカラムに MUL が設定されるようです。

UNIQUE 制約がどのカラムに対して設定されているのかを確認するには SHOW CREATE TABLE 文を使うと確認できます。

AUTO_INCREMENTを設定する(連続した数値を自動でカラムに格納する)

カラムに AUTO_INCREMENT をつけると、データを追加した時にカラムに対して現在格納されている最大の数値に 1 を追加した数値を自動で格納できる。カラムに連続した数値を自動で格納したい場合に便利。

CREATE TABLE db_name.tbl_name
  (col_name data_type AUTO_INCREMENT, ... , INDEX (col_name))

※AUTO_INCREMENTの注意事項
- テーブルごとに 1 つのカラムにしか設定できない
- AUTO_INCREMENT が設定されたカラムにはインデックスが設定されている必要がある
- AUTO_INCREMENT が設定されたカラムには DEFAULT 制約は設定できない
- AUTO_INCREMENT が設定されたカラムに正の数値を格納した場合だけ正しく動作する

AUTO_INCREMENTが設定されたカラムに次に追加される値を確認する

AUTO_INCREMENT が設定されたカラムに自動で格納される値を確認するには INFORMATION_SCHEMA.TABLES テーブルから次のように参照することができます。(下記では使用しているデータベース名が mydb 、対象のテーブル名が staff の場合です)。

select AUTO_INCREMENT from information_schema.tables where table_schema='mydb' and table_name='staff';

テーブル作成時にAUTO_INCREMENTで自動で格納される値の初期値を設定する

AUTO_INCREMENT が設定されたカラムに設定される初期値は 1 から開始されますが任意の値から開始することもできます。初期値を設定する場合の書式は次の通りです。

CREATE TABLE db_name.tbl_name
  (col_name data_type AUTO_INCREMENT, ... , INDEX (col_name))
  AUTO_INCREMENT = value

例:

create table customer(
 id int auto_increment,
 name varchar(10),
 index(id))

 auto_increment = 20;

AUTO_INCREMENTで自動で格納される値をリセットする

作成済みのテーブルで AUTO_INCREMENT によって次に自動で格納される値を指定したり、テーブルそのものは削除せずにデータだけをすべて削除した場合に AUTO_INCREMENT で自動で格納される値をリセットして 1 から開始したい場合には ALTER TABLE 文を使って変更することができます。

ALTER TABLE tbl_name AUTO_INCREMENT = value

最後に・・・引用元全部書いていたら、引用多めの記事ってOK??

現在駆け出しエンジニアとして、SQLについて学習しております。かなり引用が多いので、引用元に敬意を表すため引用元を全部書きました。

ただ、流石にそのままの引用多すぎ、とかダメな点があればご教示頂ければ幸いです。

参考

NOT NULL制約(カラムにNULLの格納を許可するかどうか)

DEFAULT制約(カラムにデフォルト値を設定する)

PRIMARY KEY制約(主キー/プライマリキーを設定する)

SQL:INDEXのメリットとデメリットについて

UNIQUE制約(ユニーク制約を設定する)

AUTO_INCREMENTを設定する(連続した数値を自動でカラムに格納する)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【laravel+mysql】新規でアプリケーションを立上げ、初めてのphp artisan migrateで詰まった件

どんな問題?

初めてPHP言語を使用して、Webアプリケーションを作成するためにlaravelとmysqlで開発環境を整え、新規作成したテーブルをmigrateした際にエラーが発生し、正常にテーブルが作成できない。

エラーの内容

ターミナルで $ php artisan migrateコマンドを入力したところ、以下のようなエラーが発生しました。
6行目の通り、1050 Table 'users' already exists...とあるように「既にuserテーブルは存在あるよ」ということです。

ターミナル
$ php artisan migrate
Migrating: 2014_10_12_000000_create_users_table

   Illuminate\Database\QueryException 

  SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'users' already exists (SQL: create table `users` (`id` bigint unsigned not null auto_increment primary key, `name` varchar(255) not null, `email` varchar(255) not null, `email_verified_at` timestamp null, `password` varchar(255) not null, `remember_token` varchar(100) null, `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:671
    667|         // If an exception occurs when attempting to run a query, we'll format the error
    668|         // message to include the bindings with SQL, which will make this exception a
    669|         // lot more helpful to the developer instead of just the database's errors.
    670|         catch (Exception $e) {
  > 671|             throw new QueryException(
    672|                 $query, $this->prepareBindings($bindings), $e
    673|             );
    674|         }
    675| 

      +9 vendor frames 
  10  database/migrations/2014_10_12_000000_create_users_table.php:24
      Illuminate\Support\Facades\Facade::__callStatic("create")

      +22 vendor frames 
  33  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

前提

macOS ver10.15.4
laravel ver4.0.0導入済み
mysql ver5.6.47導入済み
sequelproに接続済み

エラー発生までの流れ

ターミナル上で

ターミナル
$ laravel new [プロジェクト名]

コマンドで新規プロジェクト作成した際、userテーブルも自動生成されます。(password_resetsテーブルも自動生成されます。)

今回、追加でitemテーブルを作ろうと思い、

ターミナル
$ php artisan make:migration create_items_table

でitemテーブルのマイグレーションファイルを作成し、

ターミナル
$ php artisan migrate

を実行したところ、上記の通り1050 Table 'users' already exists...というエラーが出て、itemテーブルが作成できませんでした。

対処方法

userマイグレーションファイルを以下のように変更しました。

変更前

userマイグレーションファイル
上段省略
class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }
以下省略

変更後

userマイグレーションファイル
上段省略
class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        if (Schema::hasTable('users')) {
            // usersテーブルが存在していればリターンする
            return;
        }
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }
以下省略

userのマイグレーションファイルのpublic function up() の中身に

userマイグレーションファイル
if (Schema::hasTable('users')) {
            // usersテーブルが存在していればリターンする
            return;

の記述を入れて存在しているテーブルをリターンさせたところ、migrateが通りました。

なお、userを解決した後、password_resetsテーブルについても同様の現象が発生したため、同じ要領で対応しました。

最後に

phpに関しては初学者のため、まだまだ解っていないことが多いので、他に最善な解決方法等がありましたらご指摘いただけますと幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelでフォームのデータを処理する(2/2)DBのデータをトップページに表示する

はじめに

この記事はLaravelでフォームのデータを処理する(1/2)フォームで送信されたデータを取得しDBに挿入するの続きです。

今、掲示板のようなWebサービスを作成していて、Laravelで下記のような機能を実装したいです。
(1)フォームで送信されたデータを取得し、DBにデータとして挿入する。
(2)DBのデータをトップページに並べて表示する。

こんな初歩的な機能ですが、頭を抱えまくったのでメモしておきます。Laravelでこれを実現するには、色々な方法があるみたいですが、初心者の時速40kmの走行方法(教習所内)をメモしておきたいと思います。今回は(2)を実装していきます。

環境:Laravel 7、MAMP 5.7
MAMP以外をご利用の方はそこだけ貴方の環境に合わせて変換していただければと思います。

1)DBにデータが入っていることを確認する

言わずもがなですが、DBが空だと何も表示できないので、ダミーでいいのでデータを入れます。

2)トップページを用意し、プログラムを埋め込む

今回はBladeテンプレートを使用し、/resources/views直下に置いています。。(非常に簡略化しています)
例はライブの感想を投稿する掲示板なので、ライブの日付(live_date)や、ミュージシャン(musician)、会場(venue)、感想(text)などを表示したいです。

index.blade.php
    <div>
     @foreach ($items as $item)
       <p>{{$item->live_date}}</p>
       <p>{{$item->musician}}</p>
       <p>{{$item->venue}}</p>
       <p>{{$item->text}}</p>
     @endforeach
    </div>

ポイント↑:

  • いきなり{{$item->live_date}}みたいなプログラムを埋め込んでしまっていますが、最初は普通にHTMLだけで静的なサイトを準備して、ダミーでデータも書き込んでおいて、あとでその部分をプログラムで書き換えるのがいいと思います。
  • @はディレクティブと呼ばれ、Blade内でここに構文(ifなど)的なプログラムを書くよーという合図です。
  • foreachで$itemsという配列変数を受け取り、それを$itemとして一つずつ抜き出していきます。
  • その$itemは{{$item->live_date}}で使用されます。
  • が、ここに$itemsという変数を渡して上げないといけません。それが次のコントローラの役割です。

3)コントローラ

2で作ったページに渡す変数を定義し、そのページ自体を返すという設定をします。第1話で作ったControllerで、/app/Http/Controllersフォルダに配置しています。

PostController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use Illuminate\Support\Facades\DB; //DB接続のクラス

class PostController extends Controller
{
    //こちらを追加
    public function index(Request $request)
    {
        $items = DB::select('select * from reviews');
        return view('index', ['items' => $items]);
    }

ポイント↑:

  • DB::selectでDBの全てのデータ*を呼び出し、index.blade.phpに渡す変数$itemsに代入します。
  • Viewsフォルダ直下にあるindex(.blade.php)を呼び出し、第二パラメータでitemsという名前で、$itemsの値をindex(.blade.php)に渡してねと指示しています。この'items'がview(index.blade.php)内の$itemsと値が一致していないときちんとリンクしません。$のあるなしでややこしいことになっていますが...
  • あとはこのコントローラとアクションメソッドを呼び出す設定をしてあげればよくて、それをRoutingで行います。

4)ルーティング

web.php
<?php

use Illuminate\Support\Facades\Route; //デフォルトで書いてあるクラス

Route::get('/', 'PostController@index'); //こちらを追加

ポイント↑:

  • 第1パラメータは'/'、つまり、トップページ(=Document Rootを設定しているアドレス)にアクセスがあったらという条件設定
  • 第2パラメータ、PostControllerを呼び出し、そこにあるindexメソッドアクションを、、
  • 呼び起こしなさい(=Route::get)という命令文

5)成功

この状態でドキュメントルートに設定しているページにアクセスすると、DBの情報が存在しているだけ全てトップページに表示されるはずです。

うまく行かない場合のヒント

  • 私は当初、ルーティングのRoute::getをRoute::postにするという、ブレーキとアクセスを踏み間違えるようなミスで、エラーを起こしていました。
  • $items$itemなどの複数形のsのあるなし、$の付け忘れ、その他スペルミスはないか。

最後に

もし何かご指摘などありましたら、コメント欄などで頂戴できますと幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MACでmysqlをDLした後にユーザーを設定せずに出たエラーへの解決

mysql を mac なのでHome brewでDLしました。
https://qiita.com/hkusu/items/cda3e8461e7a46ecf25d
ユーザー名の設定をしていなく、mysql.infoschemaと出てしまいました。

image.png

このmysql.infoschemaをpythonに変更しようと、

rename user mysql.infoschema@localhost to python@localhost;

でユーザー名変更しようとしたところ、

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.infoschema@localhost to python@localhost' at line 1

とエラーが出ました。
この場合は、シンプルに新規にユーザー名の変更ではなく、設定を行うとうまく行きました。

ユーザー名の設定
https://qiita.com/YoshitakaOkada/items/f434bb0bc493ff9cd65b#%E3%83%A6%E3%83%BC%E3%82%B6%E4%BD%9C%E6%88%90

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む