CodingReptile ゆるゆると技術に関するメモを貯めていく 2016-11-07T02:33:30+09:00 bcsaitama Hatena::Blog hatenablog://blog/6653812171392917649 【Unity】SampleAsset の ThirdPersonCharacter のスクリプトを読む(キャラ移動の準備編) hatenablog://entry/10328749687192202324 2016-11-07T02:33:30+09:00 2016-11-07T02:33:30+09:00 前回 は変数の宣言部分を読んだので、続いて ThirdPersonCharacter.cs の中身をメソッド毎に読んでいきます。 void Start() 初期化がされています。全ての変数はあらかじめ宣言されており特別なことは特にしていないです。 唯一気になったのは 41 行目。 m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ; OR 演算子を使う場合、「左側を評… <p><a href="http://coding-reptile.hateblo.jp/entry/2016/10/27/034209">前回</a> は変数の宣言部分を読んだので、続いて ThirdPersonCharacter.cs の中身をメソッド毎に読んでいきます。</p> <h3>void Start()</h3> <p>初期化がされています。全ての変数はあらかじめ宣言されており特別なことは特にしていないです。</p> <p>唯一気になったのは 41 行目。</p> <pre class="code lang-c" data-lang="c" data-unlink>m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ; </pre> <p>OR <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>を使う場合、「左側を評価して false なら右側を評価する」<br> という使い方がされることがありますが、この場合は素直に bit 演算です。</p> <p>論理 OR <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>の結果が m_Rigidbody.constraints にセットされているようです。<br> 試しに出力してみると以下の結果になりました。</p> <pre class="code lang-c" data-lang="c" data-unlink>Debug.Log(RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezePositionY) =&gt; <span class="synConstant">6</span> Debug.Log(RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezePositionZ) =&gt; <span class="synConstant">10</span> Debug.Log(RigidbodyConstraints.FreezePositionY | RigidbodyConstraints.FreezePositionZ) =&gt; <span class="synConstant">12</span> </pre> <p>先頭 1 bit は全てなし(default)で、2 ~ 4bit 目が Position X, Y, Z のフラグになっています。<br> Rotation はもっと後ろの bit で管理されているようですね。<br> このようなフラグ管理は他の unity object でも同じなのではないでしょうか。<br></p> <h3>public void Move(Vector3 move, bool crouch, bool jump)</h3> <p>入力値を元にキャラクターを動かすメソッド。<br> 移動方向、しゃがみ状態、ジャンプ状態を引数として受け取っています。</p> <p>ThirdPersonCharacter ではキー入力した際に、入力した方向が(キャラクタのローカル座標系ではなく)カメラから見てどちらか、という基準でキャラクタを動かします。また、すぐに入力方向に移動を開始するのではなく、入力方向に対してキャラクタが正面を向くまでキャラクタを回転させます。つまり、グローバル座標における方向ベクトルがキャラクタのローカル座標における正面方向と一致させる必要があります。<br></p> <p>53 行目の InverseTransformDirection はそのためのベクトルの変換をしています。inverse って逆数かなにかを示しているのかと勘ぐってしまいますが、ローカル座標からグローバル座標への変換の逆、という意味ですね。<br></p> <p>続く 55 行目では、ProjectOnPlane を使用して、変換した move ベクトルを地面に投影しています。m_GroundNormal は CheckGroundStatus の中で更新されており、地面に対する法線ベクトルが代入されています。<br></p> <p>平面を移動する場合と坂を移動する場合で同じ速度になるようにしているということですね。</p> <p>56 行目の Mathf.<a class="keyword" href="http://d.hatena.ne.jp/keyword/Atan2">Atan2</a> では何度方向転換する必要があるかを算出しています。move.z が現在の正面方向になるので、入力した方向との角度の差分は tan(move.x / move.z) で出すことができます。角度は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%B8%A5%A2%A5%F3">ラジアン</a>で m_TurnAmount に格納されます。後は ApplyExtraTurnRotation() でキャラクタを回転させます。</p> <h3>void CheckGroundStatus()</h3> <p>地面に接しているか否かを判定して、それぞれの場合のパラメータを設定しています。<br> Physics.Raycast の第一引数は ray を投射する位置となり、現在位置から上方向に 0.1f 分のオフセットを含めて設定しています。(キャラクタのオブジェクトは足の裏が基準位置となっているため)<br> 第二引数は ray の投射方向なので重力方向です。<br> 第四引数は ray の投射距離の制限です。</p> <p>(最初、すぐには 0.1f の意味を解釈できなかったので、この 0.1f は m_CheckGroundOffset みたいな変数で設定してあったら良かったのになぁと思いました。)</p> <p>if 文の中では、接地フラグ・地面との法線ベクトル・ルートモーションの有効/無効化 をしています。</p> <h3>void ApplyExtraTurnRotation()</h3> <p>キャラクタを(ユーザが入力した方向に向くように)回転させます。<br> 秒間何度回転させるかは Mathf.lerp で算出します。default の設定だと m_ForwardAmount(0 ~ 1)の値に応じて 180 ~ 360 度の間で決定されます。Time.deltaTime は前フレームからの経過時間を返すので、unity 上での処理に時間がかかった場合でも、実時間ベースでは正しい移動量となるように処理がされます。</p> <h3>void HandleGroundedMovement(crouch, jump)</h3> <p>ジャンプ中、かつ、しゃがんでいないときの状態を処理します。<br> m_Animator.GetCurrentAnimatorStateInfo(0) の引数はレイヤーインデックスとなっています。Animator ウィンドウで確認すると、今回は BaseLayer しかないため、0 しかありません。<br> if 文に入る状態を満たしていたら、m_Rigidbody.velocity に m_JumpPower を加味したベクトルをセットします。</p> <h3>void HandleAirborneMovement()</h3> <p>空中での動きを制御します。<br> 162 行目では<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BB%B0%B9%E0%B1%E9%BB%BB%BB%D2">三項演算子</a>を使って m_GroundCheckDistance の値をセットしています。CheckGroundStatus() では足裏から上方向に 0.1f のオフセットした上で下方向に 0.1f の ray を投射していました。落下中は m_GroundCheckDistance が 0.01f になるので ray が地面に届かなくなります。<br> 0.1f に戻す判定は CheckGroundStatus() ではなく、このメソッド内での処理で行うということのようです。(直感的には CheckGroundStatus() でやりそうですが)</p> <p><br> <br> <br> というわけで、今回はキャラの移動に必要な判定や値のセット部分を読みました。 疲れたのでアニメーションの適用部分としゃがみモーションに関する部分は次回に。。</p> <p>次回読むところ</p> <ul> <li>void UpdateAnimator(Vector3 move)</li> <li>public void OnAnimatorMove()</li> <li>void PreventStandingInLowHeadroom()</li> <li>void ScaleCapsuleForCrouching(bool crouch)</li> </ul> bcsaitama 【Unity】SampleAsset の ThirdPersonCharacter のスクリプトを読む(変数の宣言編) hatenablog://entry/10328749687191456062 2016-10-27T03:42:09+09:00 2016-10-27T03:42:09+09:00 先日、MMD モデルを Unity 上で動かす際、SampleAsset の ThirdPersonController を利用することでお手軽にやりたかったことが実現できました。(ref. Unity内でMMDモデルを自由に走らせる手軽な方法 - テラシュールブログ) unity および c# の初心者としては、オブジェクトの操作という基本的な実装を担っているスクリプトはしっかり抑えておきたいところです。将来的に拡張して利用したりすることも考えて、勉強がてら以下の2つのスクリプトの中身をじっくり読んでいきます。なお、参考資料は記事の最後にまとめています。 ThirdPersonCharact… <p>先日、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MMD">MMD</a> モデルを Unity 上で動かす際、SampleAsset の ThirdPersonController を利用することでお手軽にやりたかったことが実現できました。(ref. <a href="http://tsubakit1.hateblo.jp/entry/2014/09/27/235941">Unity&#x5185;&#x3067;MMD&#x30E2;&#x30C7;&#x30EB;&#x3092;&#x81EA;&#x7531;&#x306B;&#x8D70;&#x3089;&#x305B;&#x308B;&#x624B;&#x8EFD;&#x306A;&#x65B9;&#x6CD5; - &#x30C6;&#x30E9;&#x30B7;&#x30E5;&#x30FC;&#x30EB;&#x30D6;&#x30ED;&#x30B0;</a>)</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/b/bcsaitama/20161027/20161027023050.png" alt="f:id:bcsaitama:20161027023050p:plain" title="f:id:bcsaitama:20161027023050p:plain" class="hatena-fotolife" itemprop="image"></span></p> <p>unity および <a class="keyword" href="http://d.hatena.ne.jp/keyword/c%23">c#</a> の初心者としては、オブジェクトの操作という基本的な実装を担っている<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>はしっかり抑えておきたいところです。将来的に拡張して利用したりすることも考えて、勉強がてら以下の2つの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>の中身をじっくり読んでいきます。なお、参考資料は記事の最後にまとめています。</p> <ul> <li>ThirdPersonCharacter.cs</li> <li>ThirdPersonUserControl.cs</li> </ul> <p>一度に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>の全てを読んでまとめるのは骨が折れるので、今回は変数の宣言部分に絞ってみます。</p> <pre class="code lang-c" data-lang="c" data-unlink> [SerializeField] <span class="synType">float</span> m_MovingTurnSpeed = <span class="synConstant">360</span>; [SerializeField] <span class="synType">float</span> m_StationaryTurnSpeed = <span class="synConstant">180</span>; [SerializeField] <span class="synType">float</span> m_JumpPower = <span class="synConstant">12f</span>; [Range(<span class="synConstant">1f</span>, <span class="synConstant">4f</span>)][SerializeField] <span class="synType">float</span> m_GravityMultiplier = <span class="synConstant">2f</span>; [SerializeField] <span class="synType">float</span> m_RunCycleLegOffset = <span class="synConstant">0.2f</span>; <span class="synComment">//specific to the character in sample assets, will need to be modified to work with others</span> [SerializeField] <span class="synType">float</span> m_MoveSpeedMultiplier = <span class="synConstant">1f</span>; [SerializeField] <span class="synType">float</span> m_AnimSpeedMultiplier = <span class="synConstant">1f</span>; [SerializeField] <span class="synType">float</span> m_GroundCheckDistance = <span class="synConstant">0.1f</span>; Rigidbody m_Rigidbody; Animator m_Animator; <span class="synType">bool</span> m_IsGrounded; <span class="synType">float</span> m_OrigGroundCheckDistance; <span class="synType">const</span> <span class="synType">float</span> k_Half = <span class="synConstant">0.5f</span>; <span class="synType">float</span> m_TurnAmount; <span class="synType">float</span> m_ForwardAmount; Vector3 m_GroundNormal; <span class="synType">float</span> m_CapsuleHeight; Vector3 m_CapsuleCenter; CapsuleCollider m_Capsule; <span class="synType">bool</span> m_Crouching; </pre> <p>パッと見てまず思ったのは private なのか public なのか分からない! ということ。<br> <a class="keyword" href="http://d.hatena.ne.jp/keyword/c%23">c#</a> では変数の宣言時に<span style="color: #ff0000">アクセス修飾子を付けない場合は、自動的に private</span> になるそうです。へ〜。</p> <p>次に目につくのは、いちいち変数の先頭についている <code>m_</code>。 inspecter 上では消えている。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/b/bcsaitama/20161027/20161027025533.png" alt="f:id:bcsaitama:20161027025533p:plain" title="f:id:bcsaitama:20161027025533p:plain" class="hatena-fotolife" itemprop="image"></span></p> <p>調べてみると、<code>m_</code> , <code>_</code> , <code>k</code> などはどれも private 変数の先頭につけて他の変数と明確に区別するためのもののよう。 今プロジェクトで書いている <a class="keyword" href="http://d.hatena.ne.jp/keyword/perl">perl</a> のコードでは <code>_</code> を使っていますが、それと同じということでした。 unity では <a href="https://docs.unity3d.com/ja/current/ScriptReference/ObjectNames.NicifyVariableName.html">ObjectNames.NicifyVariableName</a> が inspecter に表示するときにこれを消してくれている。</p> <p>次に、<code>[SerializeField]</code>。これは <a href="https://docs.unity3d.com/ja/current/ScriptReference/SerializeField.html:title">公式ドキュメント</a> によると</p> <pre class="code" data-lang="" data-unlink>Unity が private フィールドを強制的にシリアライズします。 ... Unity がスクリプトをシリアライズする際、public フィールドのみシリアライズします。 それに加えて Unity で private フィールドをシリアライズさせたい場合、 フィールドに SerializeField 属性を追加できます。</pre> <p>と書いてあります。 <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%A2%A5%E9%A5%A4%A5%BA">シリアライズ</a>は「オブジェクトを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%A4">バイ</a>ト列に変換して外部と受け渡しできるようにすること」なので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%A2%A5%E9%A5%A4%A5%BA">シリアライズ</a>していないものは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>の中でしか利用できません。端的に言うと、 <span style="color: #ff0000">private 変数は inspecter 上に表示されず、値の操作ができません</span>、ということ。<br> しかし、それでは不便なので SerializeField 属性を付けて inspecter から気軽に値を変えられるようにしているのですね。</p> <p>最後に、もうひとつの attribute である <code>[Range(1f, 4f)]</code>。<br> <code>m_GravityMultiplier</code> がこれを利用していますが、名前通り変数のレンジを指定するものです。inspecter 上では値を調整するための UI が提供さています。便利!</p> <h3>まとめ</h3> <ul> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/c%23">c#</a> では変数宣言時にアクセス修飾子を付けない場合は、自動的に private になる</li> <li><code>m_</code> , <code>s_</code> , <code>_</code> などを変数の先頭につけていても inspecter 上はそれらが除かれて表示される</li> <li>inspecter から気軽に private 変数の値を変えたい場合には、SerializeField 属性を付ける</li> <li>Range 属性を付けると値の制約が設定され、inspecter 上の UI が提供される</li> </ul> <p>変数の宣言だけ見てみましたがしっかり収穫がありました。 どれも基礎的なことですが、ちゃんと理解しておくの大事。</p> <h3>参考URL</h3> <ul> <li><a href="http://tsubakit1.hateblo.jp/entry/2014/09/27/235941">Unity&#x5185;&#x3067;MMD&#x30E2;&#x30C7;&#x30EB;&#x3092;&#x81EA;&#x7531;&#x306B;&#x8D70;&#x3089;&#x305B;&#x308B;&#x624B;&#x8EFD;&#x306A;&#x65B9;&#x6CD5; - &#x30C6;&#x30E9;&#x30B7;&#x30E5;&#x30FC;&#x30EB;&#x30D6;&#x30ED;&#x30B0;</a></li> <li><a href="http://masa795.hatenablog.jp/entry/2013/11/24/235259">Inspector&#x3067;&#x8868;&#x793A;&#x3055;&#x308C;&#x308B;&#x5909;&#x6570;&#x306E;&#x6587;&#x5B57;&#x5217;&#x306B;&#x5909;&#x63DB;&#x3059;&#x308B; - &#x9752;&#x7A7A;&#x306E;&#x6708;</a></li> <li><a href="http://qiita.com/RyotaMurohoshi/items/fe28abc91e24bc90a637">C#&#x3067;private&#x66F8;&#x304D;&#x307E;&#x3059;&#x304B;&#xFF1F;&#x301C;Java&#x3068;C#&#x3067;&#x30AF;&#x30E9;&#x30B9;&#x30E1;&#x30F3;&#x30D0;&#x306B;&#x30A2;&#x30AF;&#x30BB;&#x30B9;&#x4FEE;&#x98FE;&#x5B50;&#x3092;&#x66F8;&#x304B;&#x306A;&#x3044;&#x6642;&#x306E;&#x9055;&#x3044;&#x301C;&#x30A4;&#x30F3;&#x30BF;&#x30FC;&#x30D5;&#x30A7;&#x30FC;&#x30B9;&#x306B;&#x3064;&#x3044;&#x3066;&#x3082; - Qiita</a></li> <li><a href="http://tsubakit1.hateblo.jp/entry/2015/01/03/203843">Unity&#x306E;Attribute&#xFF08;&#x5C5E;&#x6027;&#xFF09;&#x306B;&#x3064;&#x3044;&#x3066;&#x307E;&#x3068;&#x3081;&#x3066;&#x30E1;&#x30E2;&#x308B;&#x3002; - &#x30C6;&#x30E9;&#x30B7;&#x30E5;&#x30FC;&#x30EB;&#x30D6;&#x30ED;&#x30B0;</a></li> </ul> bcsaitama SQLステートメントとMySQLで一貫性読み取りが機能しない場合 hatenablog://entry/6653812171403262148 2016-06-30T01:32:39+09:00 2016-10-27T03:51:13+09:00 うっかり運用中のサービスでユーザから参照されるテーブルのパーティションを作成してしまい、MySQLの一貫性読み取りが機能しない場合に遭遇したのでまとめ。ついでに SQL ステートメントについてちゃんとドキュメントを読んだ。 一貫性読み取り トランザクション分離レベルが REPEATABLE READ である場合、同一トランザクション内では最初の SELECT 文を発行した時点でスナップショットが作成され、以降はそのスナップショットを参照するため他のトランザクションによる変更の影響を受けない。 SQL ステートメント DCL データ制御言語 (Data Control Language)。権限を… <p>うっかり運用中のサービスでユーザから参照されるテーブルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>を作成してしまい、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>の一貫性読み取りが機能しない場合に遭遇したのでまとめ。ついでに <a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8">ステートメント</a>についてちゃんとドキュメントを読んだ。</p> <h2>一貫性読み取り</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B6%A5%AF%A5%B7%A5%E7%A5%F3">トランザクション</a>分離レベルが REPEATABLE READ である場合、同一<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B6%A5%AF%A5%B7%A5%E7%A5%F3">トランザクション</a>内では最初の SELECT 文を発行した時点でスナップショットが作成され、以降はそのスナップショットを参照するため他の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B6%A5%AF%A5%B7%A5%E7%A5%F3">トランザクション</a>による変更の影響を受けない。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8">ステートメント</a></h2> <h4>DCL</h4> <p>データ制御言語 (Data Control Language)。権限を管理するための <a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8">ステートメント</a>。以下の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8">ステートメント</a>が含まれる。</p> <ul> <li>GRANT(権限の付与)</li> <li>REVOKE(権限の削除)</li> </ul> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/DML">DML</a></h4> <p>データ操作言語 (Data Manipulation Language)。個々のテーブルを操作するための <a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8">ステートメント</a>。以下の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8">ステートメント</a>が含まれる。</p> <ul> <li>INSERT</li> <li>UPDATE</li> <li>DELETE</li> <li>SELECT .. FOR UPDATE</li> </ul> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/DDL">DDL</a></h4> <p>データ定義言語 (Data Definition Language)。データベース自体を操作するための <a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8">ステートメント</a>。以下の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8">ステートメント</a>が含まれる。</p> <ul> <li>CREATE</li> <li>ALTER TABLE</li> <li>DROP TABLE</li> <li>TRUNCATE(DELETE 文とは動作が異なる)</li> </ul> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/DDL">DDL</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8">ステートメント</a>は自動的に現在の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B6%A5%AF%A5%B7%A5%E7%A5%F3">トランザクション</a>をコミットし、それらを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A1%BC%A5%EB%A5%D0%A5%C3%A5%AF">ロールバック</a>することはできない。</p> <h2>一貫性読み取りが機能しない場合</h2> <p>特定の <a class="keyword" href="http://d.hatena.ne.jp/keyword/DDL">DDL</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8">ステートメント</a>では、一貫性読み取りが機能しない。</p> <ul> <li><p>DROP TABLE</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a> が削除されたテーブルを使用できず、そのテーブルは <a class="keyword" href="http://d.hatena.ne.jp/keyword/InnoDB">InnoDB</a> によって破棄されるため、一貫性読み取りが機能しない。</p></li> <li><p>ALTER TABLE</p> <p>元のテーブルの一時コピーが作成され、元のテーブルは一時コピーが構築されるときに削除される。そのため、一貫性読み取りが機能しない。<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a> 5.6.6 時点では、ER_TABLE_DEF_CHANGED エラー「Table definition has changed, please retry transaction」が返される。</p></li> </ul> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>作成は ALTER TABLE なので、以下のような順序で操作が行われるとエラーとなってしまう。</p> <ol> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B6%A5%AF%A5%B7%A5%E7%A5%F3">トランザクション</a>開始</li> <li>tableA の参照クエリを発行 (ok)</li> <li>tableA の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>作成</li> <li>tableA の参照クエリを発行 (error)</li> </ol> <h2>参考URL</h2> <ul> <li><a href="https://dev.mysql.com/doc/refman/5.6/ja/innodb-consistent-read.html">MySQL :: MySQL 5.6 &#x30EA;&#x30D5;&#x30A1;&#x30EC;&#x30F3;&#x30B9;&#x30DE;&#x30CB;&#x30E5;&#x30A2;&#x30EB; :: 14.2.4 &#x4E00;&#x8CAB;&#x6027;&#x975E;&#x30ED;&#x30C3;&#x30AF;&#x8AAD;&#x307F;&#x53D6;&#x308A;</a></li> <li><a href="https://dev.mysql.com/doc/refman/5.6/ja/glossary.html#glos_ddl">MySQL :: MySQL 5.6 &#x30EA;&#x30D5;&#x30A1;&#x30EC;&#x30F3;&#x30B9;&#x30DE;&#x30CB;&#x30E5;&#x30A2;&#x30EB; :: MySQL &#x7528;&#x8A9E;&#x96C6;</a></li> <li><iframe src="//hatenablog-parts.com/embed?url=http%3A%2F%2Ftech.kayac.com%2Farchive%2Frepeatable_read.html" title="世界の何処かで MySQL(InnoDB)の REPEATABLE READ に嵌る人を1人でも減らすために | tech.kayac.com - KAYAC engineers&#39; blog" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="http://tech.kayac.com/archive/repeatable_read.html">tech.kayac.com</a></cite></li> </ul> bcsaitama Redshift で UNIX time を TIMESTAMP (タイムゾーン有) に変換する hatenablog://entry/6653812171402287209 2016-06-23T00:33:51+09:00 2016-10-27T03:50:57+09:00 Amazon Redshift で時刻が UNIX time で記録されており TIMESTAMP 型に直したくて悩んだ。integer なので CAST が使えない。 で、結論から言うとこう。 select *, CONVERT_TIMEZONE('JST', TIMESTAMP 'epoch' + unix_time * INTERVAL '1 second') time_stamp from user limit 1; postgreSQL自体の再起動が許されるのであれば、以下でタイムゾーンを設定してから再起動でタイムゾーン変更ができるらしい。タイムゾーンの設定が合っていれば CONVE… <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a> Redshift で時刻が <a class="keyword" href="http://d.hatena.ne.jp/keyword/UNIX">UNIX</a> time で記録されており TIMESTAMP 型に直したくて悩んだ。integer なので <code>CAST</code> が使えない。</p> <p>で、結論から言うとこう。</p> <pre class="code lang-sql" data-lang="sql" data-unlink><span class="synStatement">select</span> *, CONVERT_TIMEZONE(<span class="synConstant">'JST'</span>, TIMESTAMP <span class="synConstant">'epoch'</span> + unix_time * INTERVAL <span class="synConstant">'1 second'</span>) time_stamp <span class="synSpecial">from</span> <span class="synSpecial">user</span> limit <span class="synConstant">1</span>; </pre> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/postgreSQL">postgreSQL</a>自体の再起動が許されるのであれば、以下で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BF%A5%A4%A5%E0%A5%BE%A1%BC%A5%F3">タイムゾーン</a>を設定してから再起動で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BF%A5%A4%A5%E0%A5%BE%A1%BC%A5%F3">タイムゾーン</a>変更ができるらしい。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BF%A5%A4%A5%E0%A5%BE%A1%BC%A5%F3">タイムゾーン</a>の設定が合っていれば <code>CONVERT_TIMEZONE</code> が不要になる。</p> <pre class="code lang-sql" data-lang="sql" data-unlink>timezone = JST<span class="synConstant">-9</span> </pre> <p>参考: * <a href="http://blog.okazuki.jp/entry/20130515/1368599076">PostgreSQL&#x306E;&#x30C7;&#x30D5;&#x30A9;&#x30EB;&#x30C8;&#x306E;&#x30BF;&#x30A4;&#x30E0;&#x30BE;&#x30FC;&#x30F3; - &#x304B;&#x305A;&#x304D;&#x306E;Blog@hatena</a> * <a href="http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_CAST_function.html">CAST &#x95A2;&#x6570;&#x304A;&#x3088;&#x3073; CONVERT &#x95A2;&#x6570; - Amazon Redshift</a></p> <h4>6/23 追記</h4> <p>DATE_ADD を使うやり方がありました。こっちの方が覚えやすそう。</p> <pre class="code" data-lang="" data-unlink>select *, DATE_ADD(&#39;second&#39;, &#34;time&#34;, &#39;1970-01-01 09:00:00&#39;) time_stamp from gacha limit 1;</pre> bcsaitama ブログ始めました hatenablog://entry/6653812171402124911 2016-06-21T23:09:21+09:00 2016-06-21T23:09:21+09:00 いわゆる技術ブログを開設しました。趣味のブログにおもむろに作ったスクリプト投下したりしてましたが、やはり別で持っていた方が良いなということで。肩肘張らずに頻度重視で、細々とした日々の学習内容を綴っていきたい所存。 いわゆる技術ブログを開設しました。<div>趣味のブログにおもむろに作った<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>投下したりしてましたが、やはり別で持っていた方が良いなということで。</div><div>肩肘張らずに頻度重視で、細々とした日々の学習内容を綴っていきたい所存。</div> bcsaitama